mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/24] clk updates
@ 2021-06-02  9:54 Sascha Hauer
  2021-06-02  9:54 ` [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK Sascha Hauer
                   ` (23 more replies)
  0 siblings, 24 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

The barebox clk framework has diverged a lot from Linux. Specifically
the separation of a struct clk_hw from struct clk causes some pain when
porting over code from Linux. This series aims to reduce the differences
a bit. New this time is the addition of the rk3568 clock code which is
a first step to get rk3568 up.

Changes since v1:
- Make exported clk ops const
- Add more patches to get closer to Linux
- Update Rockchip Clock support to current Linux
- Add rk3568 clk support

Sascha Hauer (24):
  clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK
  clk: introduce clk init op
  clk: rename clk_register() to bclk_register()
  clk: introduce struct clk_hw
  clk: introduce clk_register()
  clk: divider: Make clk_divider_ops const
  clk: divider: Add ro ops
  clk: divider: Make clk_mux_ops const
  clk: mux: Add ro ops
  clk: move fixed_factor to include/linux/clk.h
  Add rational_best_approximation()
  clk: Update fractional divider from Linux
  clk: Add lock to different clock types
  clk: Add Linux functions to register a divider
  clk: Add Linux functions to register a fixed factor clock
  clk: Add Linux functions to register a gate
  clk: Add Linux functions to register a mux
  clk: Add CLK_GET_RATE_NOCACHE
  clk: Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE
  clk: implement CLK_SET_RATE_UNGATE
  clk: implement set/get phase
  regmap: Add regmap_read_poll_timeout
  clk: rockchip: Update to current Linux
  clk: Rockchip: Add rk3568 clk support

 drivers/clk/at91/clk-audio-pll.c        |  103 +-
 drivers/clk/at91/clk-generated.c        |   42 +-
 drivers/clk/at91/clk-h32mx.c            |   22 +-
 drivers/clk/at91/clk-i2s-mux.c          |   24 +-
 drivers/clk/at91/clk-main.c             |  126 +-
 drivers/clk/at91/clk-master.c           |   32 +-
 drivers/clk/at91/clk-peripheral.c       |   72 +-
 drivers/clk/at91/clk-pll.c              |   40 +-
 drivers/clk/at91/clk-plldiv.c           |   26 +-
 drivers/clk/at91/clk-programmable.c     |   32 +-
 drivers/clk/at91/clk-sam9x60-pll.c      |   28 +-
 drivers/clk/at91/clk-slow.c             |   20 +-
 drivers/clk/at91/clk-smd.c              |   36 +-
 drivers/clk/at91/clk-system.c           |   28 +-
 drivers/clk/at91/clk-usb.c              |   92 +-
 drivers/clk/at91/clk-utmi.c             |   32 +-
 drivers/clk/at91/sckc.c                 |  114 +-
 drivers/clk/clk-ar933x.c                |   18 +-
 drivers/clk/clk-ar9344.c                |   18 +-
 drivers/clk/clk-composite.c             |   74 +-
 drivers/clk/clk-divider.c               |   78 +-
 drivers/clk/clk-fixed-factor.c          |   44 +-
 drivers/clk/clk-fixed.c                 |   20 +-
 drivers/clk/clk-fractional-divider.c    |  133 +-
 drivers/clk/clk-gate-shared.c           |   33 +-
 drivers/clk/clk-gate.c                  |   52 +-
 drivers/clk/clk-gpio.c                  |   32 +-
 drivers/clk/clk-mux.c                   |   48 +-
 drivers/clk/clk-qoric.c                 |   34 +-
 drivers/clk/clk-stm32mp1.c              |  103 +-
 drivers/clk/clk.c                       |  207 ++-
 drivers/clk/imx/clk-composite-8m.c      |   33 +-
 drivers/clk/imx/clk-cpu.c               |   32 +-
 drivers/clk/imx/clk-frac-pll.c          |   38 +-
 drivers/clk/imx/clk-gate-exclusive.c    |   36 +-
 drivers/clk/imx/clk-gate2.c             |   45 +-
 drivers/clk/imx/clk-imx6ul.c            |    4 +-
 drivers/clk/imx/clk-pfd.c               |   34 +-
 drivers/clk/imx/clk-pll14xx.c           |   47 +-
 drivers/clk/imx/clk-pllv1.c             |   18 +-
 drivers/clk/imx/clk-pllv2.c             |   24 +-
 drivers/clk/imx/clk-pllv3.c             |   70 +-
 drivers/clk/imx/clk-sccg-pll.c          |   51 +-
 drivers/clk/loongson/clk-ls1b200.c      |   18 +-
 drivers/clk/mvebu/corediv.c             |   30 +-
 drivers/clk/mxs/clk-div.c               |   36 +-
 drivers/clk/mxs/clk-frac.c              |   30 +-
 drivers/clk/mxs/clk-lcdif.c             |   20 +-
 drivers/clk/mxs/clk-pll.c               |   32 +-
 drivers/clk/mxs/clk-ref.c               |   38 +-
 drivers/clk/rockchip/Makefile           |    3 +-
 drivers/clk/rockchip/clk-cpu.c          |   82 +-
 drivers/clk/rockchip/clk-inverter.c     |  107 ++
 drivers/clk/rockchip/clk-mmc-phase.c    |  192 +++
 drivers/clk/rockchip/clk-muxgrf.c       |   95 ++
 drivers/clk/rockchip/clk-pll.c          |  853 ++++++++++--
 drivers/clk/rockchip/clk-rk3188.c       |  363 ++---
 drivers/clk/rockchip/clk-rk3288.c       |  309 ++--
 drivers/clk/rockchip/clk-rk3568.c       | 1704 +++++++++++++++++++++++
 drivers/clk/rockchip/clk.c              |  489 +++++--
 drivers/clk/rockchip/clk.h              |  500 ++++++-
 drivers/clk/socfpga/clk-gate-a10.c      |   32 +-
 drivers/clk/socfpga/clk-periph-a10.c    |   28 +-
 drivers/clk/socfpga/clk-pll-a10.c       |   30 +-
 drivers/clk/socfpga/clk.c               |   74 +-
 drivers/clk/socfpga/clk.h               |    6 +-
 drivers/clk/tegra/clk-divider.c         |   17 +-
 drivers/clk/tegra/clk-periph.c          |   44 +-
 drivers/clk/tegra/clk-pll-out.c         |   30 +-
 drivers/clk/tegra/clk-pll.c             |   52 +-
 drivers/clk/tegra/clk.h                 |    6 +-
 drivers/clk/vexpress/clk-sp810.c        |   24 +-
 drivers/clk/zynq/clkc.c                 |  100 +-
 drivers/clk/zynqmp/clk-divider-zynqmp.c |   30 +-
 drivers/clk/zynqmp/clk-gate-zynqmp.c    |   30 +-
 drivers/clk/zynqmp/clk-mux-zynqmp.c     |   30 +-
 drivers/clk/zynqmp/clk-pll-zynqmp.c     |   48 +-
 drivers/video/imx-ipu-v3/ipu-di.c       |   17 +-
 include/linux/clk.h                     |  199 ++-
 include/linux/rational.h                |   20 +
 include/regmap.h                        |   24 +
 lib/math/Makefile                       |    1 +
 lib/math/rational.c                     |  100 ++
 83 files changed, 6089 insertions(+), 1949 deletions(-)
 create mode 100644 drivers/clk/rockchip/clk-inverter.c
 create mode 100644 drivers/clk/rockchip/clk-mmc-phase.c
 create mode 100644 drivers/clk/rockchip/clk-muxgrf.c
 create mode 100644 drivers/clk/rockchip/clk-rk3568.c
 create mode 100644 include/linux/rational.h
 create mode 100644 lib/math/rational.c

-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02 15:18   ` Ahmad Fatoum
  2021-06-02  9:54 ` [PATCH 02/24] clk: introduce clk init op Sascha Hauer
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

CLK_MUX_HIWORD_MASK is a flag of the mux clock, not a generic clock
flag.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index a4743c51b0..7977a76db9 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -34,7 +34,7 @@ static int clk_mux_set_parent(struct clk *clk, u8 idx)
 	val &= ~(((1 << m->width) - 1) << m->shift);
 	val |= idx << m->shift;
 
-	if (clk->flags & CLK_MUX_HIWORD_MASK)
+	if (m->flags & CLK_MUX_HIWORD_MASK)
 		val |= ((1 << m->width) - 1) << (m->shift + 16);
 	writel(val, m->reg);
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 02/24] clk: introduce clk init op
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
  2021-06-02  9:54 ` [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 03/24] clk: rename clk_register() to bclk_register() Sascha Hauer
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List; +Cc: Ahmad Fatoum

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/clk/clk.c   | 12 ++++++++++++
 include/linux/clk.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b04d44593b..fb5bf57e4b 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -261,6 +261,7 @@ struct clk *clk_get_parent(struct clk *clk)
 int clk_register(struct clk *clk)
 {
 	struct clk *c;
+	int ret;
 
 	list_for_each_entry(c, &clks, list) {
 		if (!strcmp(c->name, clk->name)) {
@@ -274,10 +275,21 @@ int clk_register(struct clk *clk)
 
 	list_add_tail(&clk->list, &clks);
 
+	if (clk->ops->init) {
+		ret = clk->ops->init(clk);
+		if (ret)
+			goto out;
+	}
+
 	if (clk->flags & CLK_IS_CRITICAL)
 		clk_enable(clk);
 
 	return 0;
+out:
+	list_del(&clk->list);
+	free(clk->parents);
+
+	return ret;
 }
 
 int clk_is_enabled(struct clk *clk)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index c49fe9a54c..5d05ffd1b3 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -336,6 +336,7 @@ static inline void clk_put(struct clk *clk)
 #define CLK_GATE_HIWORD_MASK	(1 << 1)
 
 struct clk_ops {
+	int 		(*init)(struct clk *clk);
 	int		(*enable)(struct clk *clk);
 	void		(*disable)(struct clk *clk);
 	int		(*is_enabled)(struct clk *clk);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 03/24] clk: rename clk_register() to bclk_register()
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
  2021-06-02  9:54 ` [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK Sascha Hauer
  2021-06-02  9:54 ` [PATCH 02/24] clk: introduce clk init op Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 04/24] clk: introduce struct clk_hw Sascha Hauer
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List; +Cc: Ahmad Fatoum

Linux has a clk_register() function with a different semantics than
barebox. Rename this function to bclk_register() so that we later
can introduce a clk_register() function with the same semantics as
Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/clk/at91/clk-audio-pll.c        | 6 +++---
 drivers/clk/at91/clk-generated.c        | 2 +-
 drivers/clk/at91/clk-h32mx.c            | 2 +-
 drivers/clk/at91/clk-i2s-mux.c          | 2 +-
 drivers/clk/at91/clk-main.c             | 8 ++++----
 drivers/clk/at91/clk-master.c           | 2 +-
 drivers/clk/at91/clk-peripheral.c       | 4 ++--
 drivers/clk/at91/clk-pll.c              | 2 +-
 drivers/clk/at91/clk-plldiv.c           | 2 +-
 drivers/clk/at91/clk-programmable.c     | 2 +-
 drivers/clk/at91/clk-sam9x60-pll.c      | 2 +-
 drivers/clk/at91/clk-slow.c             | 2 +-
 drivers/clk/at91/clk-smd.c              | 2 +-
 drivers/clk/at91/clk-system.c           | 2 +-
 drivers/clk/at91/clk-usb.c              | 6 +++---
 drivers/clk/at91/clk-utmi.c             | 2 +-
 drivers/clk/at91/sckc.c                 | 8 ++++----
 drivers/clk/clk-ar933x.c                | 2 +-
 drivers/clk/clk-ar9344.c                | 2 +-
 drivers/clk/clk-composite.c             | 2 +-
 drivers/clk/clk-divider.c               | 4 ++--
 drivers/clk/clk-fixed-factor.c          | 2 +-
 drivers/clk/clk-fixed.c                 | 2 +-
 drivers/clk/clk-fractional-divider.c    | 2 +-
 drivers/clk/clk-gate-shared.c           | 2 +-
 drivers/clk/clk-gate.c                  | 2 +-
 drivers/clk/clk-gpio.c                  | 2 +-
 drivers/clk/clk-mux.c                   | 2 +-
 drivers/clk/clk-qoric.c                 | 2 +-
 drivers/clk/clk-stm32mp1.c              | 6 +++---
 drivers/clk/clk.c                       | 2 +-
 drivers/clk/imx/clk-cpu.c               | 2 +-
 drivers/clk/imx/clk-frac-pll.c          | 2 +-
 drivers/clk/imx/clk-gate-exclusive.c    | 2 +-
 drivers/clk/imx/clk-gate2.c             | 2 +-
 drivers/clk/imx/clk-pfd.c               | 2 +-
 drivers/clk/imx/clk-pll14xx.c           | 2 +-
 drivers/clk/imx/clk-pllv1.c             | 2 +-
 drivers/clk/imx/clk-pllv2.c             | 2 +-
 drivers/clk/imx/clk-pllv3.c             | 2 +-
 drivers/clk/imx/clk-sccg-pll.c          | 2 +-
 drivers/clk/loongson/clk-ls1b200.c      | 2 +-
 drivers/clk/mvebu/corediv.c             | 2 +-
 drivers/clk/mxs/clk-div.c               | 2 +-
 drivers/clk/mxs/clk-frac.c              | 2 +-
 drivers/clk/mxs/clk-lcdif.c             | 2 +-
 drivers/clk/mxs/clk-pll.c               | 2 +-
 drivers/clk/mxs/clk-ref.c               | 2 +-
 drivers/clk/rockchip/clk-cpu.c          | 2 +-
 drivers/clk/rockchip/clk-pll.c          | 4 ++--
 drivers/clk/socfpga/clk-gate-a10.c      | 2 +-
 drivers/clk/socfpga/clk-periph-a10.c    | 2 +-
 drivers/clk/socfpga/clk-pll-a10.c       | 2 +-
 drivers/clk/socfpga/clk.c               | 6 +++---
 drivers/clk/tegra/clk-divider.c         | 2 +-
 drivers/clk/tegra/clk-periph.c          | 2 +-
 drivers/clk/tegra/clk-pll-out.c         | 2 +-
 drivers/clk/tegra/clk-pll.c             | 2 +-
 drivers/clk/vexpress/clk-sp810.c        | 2 +-
 drivers/clk/zynq/clkc.c                 | 8 ++++----
 drivers/clk/zynqmp/clk-divider-zynqmp.c | 2 +-
 drivers/clk/zynqmp/clk-gate-zynqmp.c    | 2 +-
 drivers/clk/zynqmp/clk-mux-zynqmp.c     | 2 +-
 drivers/clk/zynqmp/clk-pll-zynqmp.c     | 2 +-
 drivers/video/imx-ipu-v3/ipu-di.c       | 2 +-
 include/linux/clk.h                     | 2 +-
 66 files changed, 86 insertions(+), 86 deletions(-)

diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c
index 47bff32fe8..25be69ec6f 100644
--- a/drivers/clk/at91/clk-audio-pll.c
+++ b/drivers/clk/at91/clk-audio-pll.c
@@ -442,7 +442,7 @@ at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
 
 	frac_ck->regmap = regmap;
 
-	ret = clk_register(&frac_ck->clk);
+	ret = bclk_register(&frac_ck->clk);
 	if (ret) {
 		kfree(frac_ck);
 		return ERR_PTR(ret);
@@ -472,7 +472,7 @@ at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
 
 	apad_ck->regmap = regmap;
 
-	ret = clk_register(&apad_ck->clk);
+	ret = bclk_register(&apad_ck->clk);
 	if (ret) {
 		kfree(apad_ck);
 		return ERR_PTR(ret);
@@ -502,7 +502,7 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
 
 	apmc_ck->regmap = regmap;
 
-	ret = clk_register(&apmc_ck->clk);
+	ret = bclk_register(&apmc_ck->clk);
 	if (ret) {
 		kfree(apmc_ck);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 56b800facb..23d193f9dd 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -191,7 +191,7 @@ at91_clk_register_generated(struct regmap *regmap,
 
 	clk_generated_startup(gck);
 	hw = &gck->hw;
-	ret = clk_register(&gck->hw);
+	ret = bclk_register(&gck->hw);
 	if (ret) {
 		kfree(gck);
 		hw = ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 6052886cca..1bcd30be75 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -103,7 +103,7 @@ at91_clk_register_h32mx(struct regmap *regmap, const char *name,
 
 	h32mxclk->regmap = regmap;
 
-	ret = clk_register(&h32mxclk->hw);
+	ret = bclk_register(&h32mxclk->hw);
 	if (ret) {
 		kfree(h32mxclk);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c
index f906007ed5..6e3d1e8f59 100644
--- a/drivers/clk/at91/clk-i2s-mux.c
+++ b/drivers/clk/at91/clk-i2s-mux.c
@@ -76,7 +76,7 @@ at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
 	i2s_ck->bus_id = bus_id;
 	i2s_ck->regmap = regmap;
 
-	ret = clk_register(&i2s_ck->clk);
+	ret = bclk_register(&i2s_ck->clk);
 	if (ret) {
 		kfree(i2s_ck);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 08abb1673b..74c26a1516 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -154,7 +154,7 @@ at91_clk_register_main_osc(struct regmap *regmap,
 				  AT91_PMC_MOSCEN,
 				  AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 
-	ret = clk_register(&osc->clk);
+	ret = bclk_register(&osc->clk);
 	if (ret) {
 		free(osc);
 		return ERR_PTR(ret);
@@ -254,7 +254,7 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
 	osc->regmap = regmap;
 	osc->frequency = frequency;
 
-	ret = clk_register(&osc->clk);
+	ret = bclk_register(&osc->clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
@@ -347,7 +347,7 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
 	clkmain->clk.num_parents = 1;
 	clkmain->regmap = regmap;
 
-	ret = clk_register(&clkmain->clk);
+	ret = bclk_register(&clkmain->clk);
 	if (ret) {
 		kfree(clkmain);
 		return ERR_PTR(ret);
@@ -463,7 +463,7 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 	clkmain->parent = clk_main_parent_select(status);
 
-	ret = clk_register(&clkmain->clk);
+	ret = bclk_register(&clkmain->clk);
 	if (ret) {
 		kfree(clkmain);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index da5e316988..dcdc4fceda 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -131,7 +131,7 @@ at91_clk_register_master(struct regmap *regmap,
 	master->characteristics = characteristics;
 	master->regmap = regmap;
 
-	ret = clk_register(&master->clk);
+	ret = bclk_register(&master->clk);
 	if (ret) {
 		kfree(master);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 2b9008eb2c..055c8c3b98 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -119,7 +119,7 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
 	periph->id = id;
 	periph->regmap = regmap;
 
-	ret = clk_register(&periph->clk);
+	ret = bclk_register(&periph->clk);
 	if (ret) {
 		kfree(periph);
 		return ERR_PTR(ret);
@@ -338,7 +338,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
 	periph->layout = layout;
 	periph->range = *range;
 
-	ret = clk_register(&periph->clk);
+	ret = bclk_register(&periph->clk);
 	if (ret) {
 		kfree(periph);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
index 5cb156e784..04d915706a 100644
--- a/drivers/clk/at91/clk-pll.c
+++ b/drivers/clk/at91/clk-pll.c
@@ -304,7 +304,7 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
 	pll->div = PLL_DIV(pllr);
 	pll->mul = PLL_MUL(pllr, layout);
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
index 1cbb61bb2c..3a8b0dc9ee 100644
--- a/drivers/clk/at91/clk-plldiv.c
+++ b/drivers/clk/at91/clk-plldiv.c
@@ -95,7 +95,7 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
 
 	plldiv->regmap = regmap;
 
-	ret = clk_register(&plldiv->clk);
+	ret = bclk_register(&plldiv->clk);
 	if (ret) {
 		kfree(plldiv);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 99a0fa29a3..70a8ca6d93 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -156,7 +156,7 @@ at91_clk_register_programmable(struct regmap *regmap,
 	prog->layout = layout;
 	prog->regmap = regmap;
 
-	ret = clk_register(&prog->clk);
+	ret = bclk_register(&prog->clk);
 	if (ret) {
 		kfree(prog);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index 9ca77f8722..91c6b62667 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -311,7 +311,7 @@ sam9x60_clk_register_pll(struct regmap *regmap,
 	regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
 	pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index bcce810fa5..1768f0ad5e 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -63,7 +63,7 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
 	slowck->clk.num_parents = num_parents;
 	slowck->regmap = regmap;
 
-	ret = clk_register(&slowck->clk);
+	ret = bclk_register(&slowck->clk);
 	if (ret) {
 		kfree(slowck);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 366f2eaad5..ad376d03c9 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -127,7 +127,7 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
 	smd->regmap = regmap;
 
-	ret = clk_register(&smd->clk);
+	ret = bclk_register(&smd->clk);
 	if (ret) {
 		kfree(smd);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 77f0dff98b..db9d7b3d61 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -105,7 +105,7 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
 	sys->id = id;
 	sys->regmap = regmap;
 
-	ret = clk_register(&sys->clk);
+	ret = bclk_register(&sys->clk);
 	if (ret) {
 		kfree(sys);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index 4ca076e777..d60232f771 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -165,7 +165,7 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
 	usb->usbs_mask = usbs_mask;
 	usb->num_parents = num_parents;
 
-	ret = clk_register(&usb->clk);
+	ret = bclk_register(&usb->clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
@@ -206,7 +206,7 @@ at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; */
 	usb->regmap = regmap;
 
-	ret = clk_register(&usb->clk);
+	ret = bclk_register(&usb->clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
@@ -321,7 +321,7 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
 	usb->regmap = regmap;
 	memcpy(usb->divisors, divisors, sizeof(usb->divisors));
 
-	ret = clk_register(&usb->clk);
+	ret = bclk_register(&usb->clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 3d71cd615f..df3904e5a0 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -147,7 +147,7 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
 	utmi->regmap_pmc = regmap_pmc;
 	utmi->regmap_sfr = regmap_sfr;
 
-	ret = clk_register(&utmi->clk);
+	ret = bclk_register(&utmi->clk);
 	if (ret) {
 		kfree(utmi);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index d9898f718c..bf55589c80 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -152,7 +152,7 @@ at91_clk_register_slow_osc(void __iomem *sckcr,
 		writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
 					osc->bits->cr_osc32byp, sckcr);
 
-	ret = clk_register(&osc->clk);
+	ret = bclk_register(&osc->clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
@@ -237,7 +237,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
 	osc->frequency = frequency;
 	osc->startup_usec = startup;
 
-	ret = clk_register(&osc->clk);
+	ret = bclk_register(&osc->clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
@@ -318,7 +318,7 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
 	slowck->bits = bits;
 	slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
 
-	ret = clk_register(&slowck->clk);
+	ret = bclk_register(&slowck->clk);
 	if (ret) {
 		kfree(slowck);
 		return ERR_PTR(ret);
@@ -571,7 +571,7 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np)
 	osc->startup_usec = 1200000;
 	osc->bits = &at91sama5d4_bits;
 
-	ret = clk_register(&osc->clk);
+	ret = bclk_register(&osc->clk);
 	if (ret)
 		goto free_slow_osc_data;
 
diff --git a/drivers/clk/clk-ar933x.c b/drivers/clk/clk-ar933x.c
index 0e7f2d6a67..4727127aeb 100644
--- a/drivers/clk/clk-ar933x.c
+++ b/drivers/clk/clk-ar933x.c
@@ -84,7 +84,7 @@ static struct clk *clk_ar933x(const char *name, const char *parent,
 	f->clk.parent_names = &f->parent;
 	f->clk.num_parents = 1;
 
-	clk_register(&f->clk);
+	bclk_register(&f->clk);
 
 	return &f->clk;
 }
diff --git a/drivers/clk/clk-ar9344.c b/drivers/clk/clk-ar9344.c
index 829d4b1f91..1a25731fd5 100644
--- a/drivers/clk/clk-ar9344.c
+++ b/drivers/clk/clk-ar9344.c
@@ -89,7 +89,7 @@ static struct clk *clk_ar9344(const char *name, const char *parent,
 	f->clk.parent_names = &f->parent;
 	f->clk.num_parents = 1;
 
-	clk_register(&f->clk);
+	bclk_register(&f->clk);
 
 	return &f->clk;
 }
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index e0f543bc1c..1eb1eea68e 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -125,7 +125,7 @@ struct clk *clk_register_composite(const char *name,
 	composite->rate_clk = rate_clk;
 	composite->gate_clk = gate_clk;
 
-	ret = clk_register(&composite->clk);
+	ret = bclk_register(&composite->clk);
 	if (ret)
 		goto err;
 
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 7119dd4e59..3acce64042 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -335,7 +335,7 @@ struct clk *clk_divider(const char *name, const char *parent, unsigned clk_flags
 	d = clk_divider_alloc(name , parent, clk_flags, reg, shift, width,
 			      div_flags);
 
-	ret = clk_register(d);
+	ret = bclk_register(d);
 	if (ret) {
 		clk_divider_free(d);
 		return ERR_PTR(ret);
@@ -390,7 +390,7 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 		div->table_size++;
 	}
 
-	ret = clk_register(&div->clk);
+	ret = bclk_register(&div->clk);
 	if (ret) {
 		free(div);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index e7738775f8..ce6fe1cce7 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -73,7 +73,7 @@ struct clk *clk_fixed_factor(const char *name,
 	f->clk.parent_names = &f->parent;
 	f->clk.num_parents = 1;
 
-	ret = clk_register(&f->clk);
+	ret = bclk_register(&f->clk);
 	if (ret) {
 		free(f);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c
index d7ac59c4d4..e628b4e4e6 100644
--- a/drivers/clk/clk-fixed.c
+++ b/drivers/clk/clk-fixed.c
@@ -49,7 +49,7 @@ struct clk *clk_register_fixed_rate(const char *name,
 		fix->clk.num_parents = 1;
 	}
 
-	ret = clk_register(&fix->clk);
+	ret = bclk_register(&fix->clk);
 	if (ret) {
 		free(parent_names);
 		free(fix);
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 6f0763b05f..6955666127 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -138,7 +138,7 @@ struct clk *clk_fractional_divider(
 	if (IS_ERR(fd))
 		return fd;
 
-	ret = clk_register(fd);
+	ret = bclk_register(fd);
 	if (ret) {
 		clk_fractional_divider_free(fd);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-gate-shared.c b/drivers/clk/clk-gate-shared.c
index 54c002e836..b5a1365568 100644
--- a/drivers/clk/clk-gate-shared.c
+++ b/drivers/clk/clk-gate-shared.c
@@ -103,7 +103,7 @@ struct clk *clk_gate_shared(const char *name, const char *parent, const char *co
 
 	clk = clk_gate_shared_alloc(name , parent, companion, flags);
 
-	ret = clk_register(clk);
+	ret = bclk_register(clk);
 	if (ret) {
 		clk_gate_shared_free(clk);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 59dd643b99..6a6fd66e4e 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -100,7 +100,7 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
 
 	g = clk_gate_alloc(name , parent, reg, shift, flags, clk_gate_flags);
 
-	ret = clk_register(g);
+	ret = bclk_register(g);
 	if (ret) {
 		free(to_clk_gate(g));
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 1345fbc9ea..e47474a5cc 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -90,7 +90,7 @@ static int of_gpio_clk_setup(struct device_node *node)
 	if (ret)
 		goto no_request;
 
-	ret = clk_register(&clk_gpio->clk);
+	ret = bclk_register(&clk_gpio->clk);
 	if (ret)
 		goto no_register;
 
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 7977a76db9..b5618cefd3 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -84,7 +84,7 @@ struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
 	m = clk_mux_alloc(name, clk_flags, reg, shift, width, parents,
 			  num_parents, mux_flags);
 
-	ret = clk_register(m);
+	ret = bclk_register(m);
 	if (ret) {
 		free(to_clk_mux(m));
 		return ERR_PTR(ret);
diff --git a/drivers/clk/clk-qoric.c b/drivers/clk/clk-qoric.c
index 5bf677d94e..328570400f 100644
--- a/drivers/clk/clk-qoric.c
+++ b/drivers/clk/clk-qoric.c
@@ -339,7 +339,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
 	clk->num_parents = hwc->num_parents = i;
 	hwc->cg = cg;
 
-	ret = clk_register(clk);
+	ret = bclk_register(clk);
 	if (ret) {
 		pr_err("%s: Couldn't register %s: %d\n", __func__, clk->name, ret);
 		kfree(hwc);
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 2380bd0c21..2996877577 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -564,7 +564,7 @@ clk_stm32_register_gate_ops(const char *name,
 	clk->num_parents = 1;
 	clk->flags = flags;
 
-	ret = clk_register(clk);
+	ret = bclk_register(clk);
 	if (ret)
 		clk = ERR_PTR(ret);
 
@@ -810,7 +810,7 @@ static struct clk *clk_register_pll(const char *name,
 
 	element->reg = reg;
 
-	err = clk_register(clk);
+	err = bclk_register(clk);
 
 	if (err) {
 		kfree(element);
@@ -934,7 +934,7 @@ static struct clk *clk_register_cktim(const char *name,
 	tim_ker->apbdiv = apbdiv;
 	tim_ker->timpre = timpre;
 
-	err = clk_register(clk);
+	err = bclk_register(clk);
 	if (err) {
 		kfree(tim_ker);
 		return ERR_PTR(err);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fb5bf57e4b..7dab6a5fb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -258,7 +258,7 @@ struct clk *clk_get_parent(struct clk *clk)
 	return clk->parents[idx];
 }
 
-int clk_register(struct clk *clk)
+int bclk_register(struct clk *clk)
 {
 	struct clk *c;
 	int ret;
diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c
index f8d54ddba3..8ed899cb98 100644
--- a/drivers/clk/imx/clk-cpu.c
+++ b/drivers/clk/imx/clk-cpu.c
@@ -104,7 +104,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
 	cpu->clk.parent_names = &icpu->parent_name;
 	cpu->clk.num_parents = 1;
 
-	ret = clk_register(&cpu->clk);
+	ret = bclk_register(&cpu->clk);
 	if (ret) {
 		free(cpu);
 		return NULL;
diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c
index 48866eadf0..bc62505e57 100644
--- a/drivers/clk/imx/clk-frac-pll.c
+++ b/drivers/clk/imx/clk-frac-pll.c
@@ -210,7 +210,7 @@ struct clk *imx_clk_frac_pll(const char *name, const char *parent,
 	pll->clk.parent_names = &pll->parent;
 	pll->clk.num_parents = 1;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c
index 4bf4de8bd3..94e7467701 100644
--- a/drivers/clk/imx/clk-gate-exclusive.c
+++ b/drivers/clk/imx/clk-gate-exclusive.c
@@ -90,7 +90,7 @@ struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
 	exgate->shift = shift;
 	exgate->exclusive_mask = exclusive_mask;
 
-	ret = clk_register(&exgate->clk);
+	ret = bclk_register(&exgate->clk);
 	if (ret) {
 		free(exgate);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 88eaae8db3..3d9b9338d5 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -104,7 +104,7 @@ struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
 
 	g = clk_gate2_alloc(name , parent, reg, shift, cgr_val, flags);
 
-	ret = clk_register(g);
+	ret = bclk_register(g);
 	if (ret) {
 		free(to_clk_gate2(g));
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
index a7ca664524..88ede6c3fc 100644
--- a/drivers/clk/imx/clk-pfd.c
+++ b/drivers/clk/imx/clk-pfd.c
@@ -132,7 +132,7 @@ struct clk *imx_clk_pfd(const char *name, const char *parent,
 	pfd->clk.parent_names = &pfd->parent;
 	pfd->clk.num_parents = 1;
 
-	ret = clk_register(&pfd->clk);
+	ret = bclk_register(&pfd->clk);
 	if (ret) {
 		free(pfd);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 3fd5a49ee7..2842c740f9 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -435,7 +435,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 	val &= ~BYPASS_MASK;
 	writel(val, pll->base + GNRL_CTL);
 
-	ret = clk_register(clk);
+	ret = bclk_register(clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c
index 36192bb211..5654ed21b3 100644
--- a/drivers/clk/imx/clk-pllv1.c
+++ b/drivers/clk/imx/clk-pllv1.c
@@ -84,7 +84,7 @@ struct clk *imx_clk_pllv1(const char *name, const char *parent,
 	pll->clk.parent_names = &pll->parent;
 	pll->clk.num_parents = 1;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
index 6af2d71352..2b95be2495 100644
--- a/drivers/clk/imx/clk-pllv2.c
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -210,7 +210,7 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
 	pll->clk.parent_names = &pll->parent;
 	pll->clk.num_parents = 1;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 51e620a040..e755f6b7e7 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -409,7 +409,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 	val &= ~BM_PLL_BYPASS;
 	writel(val, pll->base);
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
index 755ece0e12..9fe4c6e6b2 100644
--- a/drivers/clk/imx/clk-sccg-pll.c
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -224,7 +224,7 @@ struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name,
         pll->clk.parent_names = &pll->parent;
         pll->clk.num_parents = 1;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/loongson/clk-ls1b200.c b/drivers/clk/loongson/clk-ls1b200.c
index 66f8e261ac..b7f4929423 100644
--- a/drivers/clk/loongson/clk-ls1b200.c
+++ b/drivers/clk/loongson/clk-ls1b200.c
@@ -82,7 +82,7 @@ static struct clk *clk_ls1b200(const char *name, const char *parent,
 	f->clk.parent_names = &f->parent;
 	f->clk.num_parents = 1;
 
-	clk_register(&f->clk);
+	bclk_register(&f->clk);
 
 	return &f->clk;
 }
diff --git a/drivers/clk/mvebu/corediv.c b/drivers/clk/mvebu/corediv.c
index 1577a2149c..79e049d18c 100644
--- a/drivers/clk/mvebu/corediv.c
+++ b/drivers/clk/mvebu/corediv.c
@@ -242,7 +242,7 @@ static int mvebu_corediv_clk_probe(struct device_d *dev)
 		corediv->desc = &soc_desc->descs[n];
 		corediv->reg = base;
 		clk_data.clks[n] = clk;
-		WARN_ON(IS_ERR_VALUE(clk_register(clk)));
+		WARN_ON(IS_ERR_VALUE(bclk_register(clk)));
 	}
 
 	return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
index 104587a8dc..9bf48c2222 100644
--- a/drivers/clk/mxs/clk-div.c
+++ b/drivers/clk/mxs/clk-div.c
@@ -96,7 +96,7 @@ struct clk *mxs_clk_div(const char *name, const char *parent_name,
 	div->divider.flags = CLK_DIVIDER_ONE_BASED;
 	div->ops = &clk_divider_ops;
 
-	ret = clk_register(&div->divider.clk);
+	ret = bclk_register(&div->divider.clk);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
index a9d390121e..6a6ce8c537 100644
--- a/drivers/clk/mxs/clk-frac.c
+++ b/drivers/clk/mxs/clk-frac.c
@@ -122,7 +122,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name,
 	frac->shift = shift;
 	frac->width = width;
 
-	ret = clk_register(&frac->clk);
+	ret = bclk_register(&frac->clk);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/clk/mxs/clk-lcdif.c b/drivers/clk/mxs/clk-lcdif.c
index 246e68068d..639f6eb6f4 100644
--- a/drivers/clk/mxs/clk-lcdif.c
+++ b/drivers/clk/mxs/clk-lcdif.c
@@ -68,7 +68,7 @@ struct clk *mxs_clk_lcdif(const char *name, struct clk *frac, struct clk *div,
 	lcdif->clk.parent_names = &lcdif->parent;
 	lcdif->clk.num_parents = 1;
 
-	ret = clk_register(&lcdif->clk);
+	ret = bclk_register(&lcdif->clk);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
index 7527a77731..7094012a94 100644
--- a/drivers/clk/mxs/clk-pll.c
+++ b/drivers/clk/mxs/clk-pll.c
@@ -101,7 +101,7 @@ struct clk *mxs_clk_pll(const char *name, const char *parent_name,
 	pll->rate = rate;
 	pll->power = power;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret)
 		ERR_PTR(ret);
 
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
index 69361f9ac3..8c12e282ad 100644
--- a/drivers/clk/mxs/clk-ref.c
+++ b/drivers/clk/mxs/clk-ref.c
@@ -148,7 +148,7 @@ struct clk *mxs_clk_ref(const char *name, const char *parent_name,
 	ref->reg = reg;
 	ref->idx = idx;
 
-	ret = clk_register(&ref->clk);
+	ret = bclk_register(&ref->clk);
 	if (ret)
 		return ERR_PTR(ret);
 
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index 71a64f71f6..732ce4207d 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -141,7 +141,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 		}
 	}
 
-	ret = clk_register(&cpuclk->hw);
+	ret = bclk_register(&cpuclk->hw);
 	if (ret) {
 		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
 		goto free_rate_table;
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 6bb8156f8c..ec5b264ac5 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -330,7 +330,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	pll->lock_shift = lock_shift;
 	pll->flags = clk_pll_flags;
 
-	ret = clk_register(&pll->hw);
+	ret = bclk_register(&pll->hw);
 	if (ret) {
 		pr_err("%s: failed to register pll clock %s : %d\n",
 			__func__, name, ret);
@@ -351,7 +351,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	if (pll_type == pll_rk3066)
 		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
 
-	ret = clk_register(pll_mux);
+	ret = bclk_register(pll_mux);
 	if (ret)
 		goto err_exit;
 
diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index 401eb20d24..57459d0e2b 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -171,7 +171,7 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 	socfpga_clk->clk.num_parents = i;
 	socfpga_clk->clk.parent_names = socfpga_clk->parent_names;
 
-	rc = clk_register(&socfpga_clk->clk);
+	rc = bclk_register(&socfpga_clk->clk);
 	if (rc) {
 		free(socfpga_clk);
 		return ERR_PTR(rc);
diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c
index 4ef00052e4..3fa636d990 100644
--- a/drivers/clk/socfpga/clk-periph-a10.c
+++ b/drivers/clk/socfpga/clk-periph-a10.c
@@ -104,7 +104,7 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 	periph_clk->clk.name = xstrdup(clk_name);
 	periph_clk->clk.ops = ops;
 
-	rc = clk_register(&periph_clk->clk);
+	rc = bclk_register(&periph_clk->clk);
 	if (rc) {
 		free(periph_clk);
 		return ERR_PTR(rc);
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index fcf31e9ea1..e0c34d8486 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -117,7 +117,7 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 	clk_pll_ops.enable = clk_socfpga_enable;
 	clk_pll_ops.disable = clk_socfpga_disable;
 
-	rc = clk_register(&pll_clk->clk);
+	rc = bclk_register(&pll_clk->clk);
 	if (rc) {
 		free(pll_clk);
 		return NULL;
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index 09e2039bd5..bdc8023820 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -97,7 +97,7 @@ static struct clk *socfpga_pll_clk(struct device_node *node)
 
 	of_property_read_u32(node, "reg", &pll->regofs);
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
@@ -169,7 +169,7 @@ static struct clk *socfpga_periph_clk(struct device_node *node)
 	of_property_read_u32(node, "reg", &periph->regofs);
 	of_property_read_u32(node, "fixed-divider", &periph->fixed_div);
 
-	ret = clk_register(&periph->clk);
+	ret = bclk_register(&periph->clk);
 	if (ret) {
 		free(periph);
 		return ERR_PTR(ret);
@@ -356,7 +356,7 @@ static struct clk *socfpga_gate_clk(struct device_node *node)
 	cs->clk.name = xstrdup(node->name);
 	cs->clk.ops = &clk_socfpga_ops;
 
-	ret = clk_register(&cs->clk);
+	ret = bclk_register(&cs->clk);
 	if (ret) {
 		free(cs);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index cc8b85520c..57868186d3 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -180,7 +180,7 @@ struct clk *tegra_clk_register_divider(const char *name,
 				  reg, flags, clk_divider_flags, shift, width,
 				  frac_width));
 
-	ret = clk_register(&divider->hw);
+	ret = bclk_register(&divider->hw);
 	if (ret) {
 		kfree(divider);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 0cd5200e84..6ed54169ad 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -153,7 +153,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
 	periph->rst_reg = clk_base + rst_offs;
 	periph->rst_shift = id & 0x1f;
 
-	ret = clk_register(&periph->hw);
+	ret = bclk_register(&periph->hw);
 	if (ret)
 		goto out_register;
 
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c
index e186275563..4b48fa2d64 100644
--- a/drivers/clk/tegra/clk-pll-out.c
+++ b/drivers/clk/tegra/clk-pll-out.c
@@ -117,7 +117,7 @@ struct clk *tegra_clk_register_pll_out(const char *name,
 	pll_out->enb_bit_idx = shift + 1;
 	pll_out->rst_bit_idx = shift;
 
-	ret = clk_register(&pll_out->hw);
+	ret = bclk_register(&pll_out->hw);
 	if (ret) {
 		tegra_clk_divider_free(pll_out->div);
 		kfree(pll_out);
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 832b3c5ea1..4b04876df1 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -678,7 +678,7 @@ static struct clk *_tegra_clk_register_pll(const char *name,
 	pll->divm_shift = PLL_BASE_DIVM_SHIFT;
 	pll->divm_width = PLL_BASE_DIVM_WIDTH;
 
-	ret = clk_register(&pll->hw);
+	ret = bclk_register(&pll->hw);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/vexpress/clk-sp810.c b/drivers/clk/vexpress/clk-sp810.c
index 968921203b..8b5c193635 100644
--- a/drivers/clk/vexpress/clk-sp810.c
+++ b/drivers/clk/vexpress/clk-sp810.c
@@ -111,7 +111,7 @@ static void clk_sp810_of_setup(struct device_node *node)
 		 */
 		clk_sp810_timerclken_set_parent(&sp810->timerclken[i].hw, 1);
 
-		clk_register(&sp810->timerclken[i].hw);
+		bclk_register(&sp810->timerclken[i].hw);
 	}
 
 	of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index 23259a5324..e4b2a855e5 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -128,7 +128,7 @@ static inline struct clk *zynq_pll_clk(enum zynq_pll_type type,
 		break;
 	}
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
@@ -186,7 +186,7 @@ static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl)
 	periph->clk.parent_names = peripheral_parents;
 	periph->clk.num_parents	= ARRAY_SIZE(peripheral_parents);
 
-	ret = clk_register(&periph->clk);
+	ret = bclk_register(&periph->clk);
 	if (ret) {
 		free(periph);
 		return ERR_PTR(ret);
@@ -248,7 +248,7 @@ static struct clk *zynq_cpu_clk(const char *name, void __iomem *clk_ctrl)
 	cpu->clk.parent_names	= cpu_parents;
 	cpu->clk.num_parents	= ARRAY_SIZE(cpu_parents);
 
-	ret = clk_register(&cpu->clk);
+	ret = bclk_register(&cpu->clk);
 	if (ret) {
 		free(cpu);
 		return ERR_PTR(ret);
@@ -355,7 +355,7 @@ static struct clk *zynq_cpu_subclk(const char *name,
 	subclk->clk.parent_names = &subclk_parent;
 	subclk->clk.num_parents	= 1;
 
-	ret = clk_register(&subclk->clk);
+	ret = bclk_register(&subclk->clk);
 	if (ret) {
 		free(subclk);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/clk-divider-zynqmp.c b/drivers/clk/zynqmp/clk-divider-zynqmp.c
index 2fe65b566a..09f63dd9b5 100644
--- a/drivers/clk/zynqmp/clk-divider-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-divider-zynqmp.c
@@ -101,7 +101,7 @@ struct clk *zynqmp_clk_register_divider(const char *name,
 	div->clk.parent_names = &div->parent;
 	div->clk.num_parents = 1;
 
-	ret = clk_register(&div->clk);
+	ret = bclk_register(&div->clk);
 	if (ret) {
 		kfree(div);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index 6f03357768..9fbc15e966 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -83,7 +83,7 @@ struct clk *zynqmp_clk_register_gate(const char *name,
 	gate->clk.parent_names = &gate->parent;
 	gate->clk.num_parents = 1;
 
-	ret = clk_register(&gate->clk);
+	ret = bclk_register(&gate->clk);
 	if (ret) {
 		kfree(gate);
 		return ERR_PTR(ret);
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index 4c15223980..c3fdf11840 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -91,7 +91,7 @@ struct clk *zynqmp_clk_register_mux(const char *name,
 	mux->clk.parent_names = parent_names;
 	mux->clk.num_parents = num_parents;
 
-	ret = clk_register(&mux->clk);
+	ret = bclk_register(&mux->clk);
 	if (ret) {
 		kfree(parent_names);
 		kfree(mux);
diff --git a/drivers/clk/zynqmp/clk-pll-zynqmp.c b/drivers/clk/zynqmp/clk-pll-zynqmp.c
index e4b759b73c..6507222568 100644
--- a/drivers/clk/zynqmp/clk-pll-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-pll-zynqmp.c
@@ -203,7 +203,7 @@ struct clk *zynqmp_clk_register_pll(const char *name,
 	pll->clk.parent_names = &pll->parent;
 	pll->clk.num_parents = 1;
 
-	ret = clk_register(&pll->clk);
+	ret = bclk_register(&pll->clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
diff --git a/drivers/video/imx-ipu-v3/ipu-di.c b/drivers/video/imx-ipu-v3/ipu-di.c
index 97613207c9..0f382f8c42 100644
--- a/drivers/video/imx-ipu-v3/ipu-di.c
+++ b/drivers/video/imx-ipu-v3/ipu-di.c
@@ -740,7 +740,7 @@ int ipu_di_init(struct ipu_soc *ipu, struct device_d *dev, int id,
 	di->clk_di_pixel.ops = &clk_di_ops;
 	di->clk_di_pixel.num_parents = 2;
 	di->clk_di_pixel.name = di->clk_name;
-	ret = clk_register(&di->clk_di_pixel);
+	ret = bclk_register(&di->clk_di_pixel);
 	if (ret)
 		goto failed_clk_register;
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5d05ffd1b3..71c5e23e91 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -494,7 +494,7 @@ long clk_parent_round_rate(struct clk *clk, unsigned long rate,
 int clk_parent_set_rate(struct clk *clk, unsigned long rate,
 				unsigned long parent_rate);
 
-int clk_register(struct clk *clk);
+int bclk_register(struct clk *clk);
 
 struct clk *clk_lookup(const char *name);
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (2 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 03/24] clk: rename clk_register() to bclk_register() Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-11  7:55   ` Ahmad Fatoum
  2021-06-02  9:54 ` [PATCH 05/24] clk: introduce clk_register() Sascha Hauer
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

In Linux the ops in struct clk_ops take a struct clk_hw * argument
instead of a struct clk * argument as in barebox. With this taking
new clk drivers from Linux requires a lot of mechanical conversions.
Instead of doing this over and over again swallow the pill once and
convert the existing barebox code over to clk_hw.

The implementation is a little different from Linux. In Linux struct clk
is only known to the core clock code. In barebox struct clk is
publically known and it is embedded into struct clk_hw. This allows
us to still use struct clk members in the clock drivers which we
currently still need, because otherwise this patch would be even
bigger.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/at91/clk-audio-pll.c        | 103 +++++++++----------
 drivers/clk/at91/clk-generated.c        |  42 ++++----
 drivers/clk/at91/clk-h32mx.c            |  22 ++---
 drivers/clk/at91/clk-i2s-mux.c          |  24 ++---
 drivers/clk/at91/clk-main.c             | 126 ++++++++++++------------
 drivers/clk/at91/clk-master.c           |  32 +++---
 drivers/clk/at91/clk-peripheral.c       |  72 +++++++-------
 drivers/clk/at91/clk-pll.c              |  40 ++++----
 drivers/clk/at91/clk-plldiv.c           |  26 ++---
 drivers/clk/at91/clk-programmable.c     |  32 +++---
 drivers/clk/at91/clk-sam9x60-pll.c      |  26 ++---
 drivers/clk/at91/clk-slow.c             |  20 ++--
 drivers/clk/at91/clk-smd.c              |  36 +++----
 drivers/clk/at91/clk-system.c           |  28 +++---
 drivers/clk/at91/clk-usb.c              |  92 ++++++++---------
 drivers/clk/at91/clk-utmi.c             |  32 +++---
 drivers/clk/at91/sckc.c                 | 114 ++++++++++-----------
 drivers/clk/clk-ar933x.c                |  18 ++--
 drivers/clk/clk-ar9344.c                |  18 ++--
 drivers/clk/clk-composite.c             |  74 +++++++-------
 drivers/clk/clk-divider.c               |  51 +++++-----
 drivers/clk/clk-fixed-factor.c          |  35 ++++---
 drivers/clk/clk-fixed.c                 |  20 ++--
 drivers/clk/clk-fractional-divider.c    |  24 ++---
 drivers/clk/clk-gate-shared.c           |  31 +++---
 drivers/clk/clk-gate.c                  |  34 ++++---
 drivers/clk/clk-gpio.c                  |  32 +++---
 drivers/clk/clk-mux.c                   |  28 +++---
 drivers/clk/clk-qoric.c                 |  34 +++----
 drivers/clk/clk-stm32mp1.c              |  97 +++++++++---------
 drivers/clk/clk.c                       |  91 ++++++++++++++---
 drivers/clk/imx/clk-composite-8m.c      |  33 +++----
 drivers/clk/imx/clk-cpu.c               |  32 +++---
 drivers/clk/imx/clk-frac-pll.c          |  38 +++----
 drivers/clk/imx/clk-gate-exclusive.c    |  36 +++----
 drivers/clk/imx/clk-gate2.c             |  34 ++++---
 drivers/clk/imx/clk-imx6ul.c            |   4 +-
 drivers/clk/imx/clk-pfd.c               |  34 +++----
 drivers/clk/imx/clk-pll14xx.c           |  45 ++++-----
 drivers/clk/imx/clk-pllv1.c             |  18 ++--
 drivers/clk/imx/clk-pllv2.c             |  24 ++---
 drivers/clk/imx/clk-pllv3.c             |  70 ++++++-------
 drivers/clk/imx/clk-sccg-pll.c          |  51 +++++-----
 drivers/clk/loongson/clk-ls1b200.c      |  18 ++--
 drivers/clk/mvebu/corediv.c             |  28 +++---
 drivers/clk/mxs/clk-div.c               |  36 +++----
 drivers/clk/mxs/clk-frac.c              |  30 +++---
 drivers/clk/mxs/clk-lcdif.c             |  20 ++--
 drivers/clk/mxs/clk-pll.c               |  32 +++---
 drivers/clk/mxs/clk-ref.c               |  38 +++----
 drivers/clk/rockchip/clk-cpu.c          |  20 ++--
 drivers/clk/rockchip/clk-pll.c          |  40 ++++----
 drivers/clk/socfpga/clk-gate-a10.c      |  32 +++---
 drivers/clk/socfpga/clk-periph-a10.c    |  28 +++---
 drivers/clk/socfpga/clk-pll-a10.c       |  30 +++---
 drivers/clk/socfpga/clk.c               |  74 +++++++-------
 drivers/clk/socfpga/clk.h               |   6 +-
 drivers/clk/tegra/clk-divider.c         |  15 +--
 drivers/clk/tegra/clk-periph.c          |  44 ++++-----
 drivers/clk/tegra/clk-pll-out.c         |  30 +++---
 drivers/clk/tegra/clk-pll.c             |  52 +++++-----
 drivers/clk/tegra/clk.h                 |   6 +-
 drivers/clk/vexpress/clk-sp810.c        |  24 ++---
 drivers/clk/zynq/clkc.c                 | 100 +++++++++----------
 drivers/clk/zynqmp/clk-divider-zynqmp.c |  30 +++---
 drivers/clk/zynqmp/clk-gate-zynqmp.c    |  30 +++---
 drivers/clk/zynqmp/clk-mux-zynqmp.c     |  30 +++---
 drivers/clk/zynqmp/clk-pll-zynqmp.c     |  48 ++++-----
 drivers/video/imx-ipu-v3/ipu-di.c       |  15 ++-
 include/linux/clk.h                     |  96 ++++++++++++++----
 70 files changed, 1502 insertions(+), 1323 deletions(-)

diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c
index 25be69ec6f..e9a30b0516 100644
--- a/drivers/clk/at91/clk-audio-pll.c
+++ b/drivers/clk/at91/clk-audio-pll.c
@@ -57,7 +57,7 @@
 #define AUDIO_PLL_FOUT_MAX	700000000UL
 
 struct clk_audio_frac {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u32 fracr;
 	u8 nd;
@@ -65,7 +65,7 @@ struct clk_audio_frac {
 };
 
 struct clk_audio_pad {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 qdaudio;
 	u8 div;
@@ -73,19 +73,19 @@ struct clk_audio_pad {
 };
 
 struct clk_audio_pmc {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 qdpmc;
 	const char *parent_name;
 };
 
-#define to_clk_audio_frac(clk) container_of(clk, struct clk_audio_frac, clk)
-#define to_clk_audio_pad(clk) container_of(clk, struct clk_audio_pad, clk)
-#define to_clk_audio_pmc(clk) container_of(clk, struct clk_audio_pmc, clk)
+#define to_clk_audio_frac(_hw) container_of(_hw, struct clk_audio_frac, hw)
+#define to_clk_audio_pad(_hw) container_of(_hw, struct clk_audio_pad, hw)
+#define to_clk_audio_pmc(_hw) container_of(_hw, struct clk_audio_pmc, hw)
 
-static int clk_audio_pll_frac_enable(struct clk *clk)
+static int clk_audio_pll_frac_enable(struct clk_hw *hw)
 {
-	struct clk_audio_frac *frac = to_clk_audio_frac(clk);
+	struct clk_audio_frac *frac = to_clk_audio_frac(hw);
 
 	regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
 			   AT91_PMC_AUDIO_PLL_RESETN, 0);
@@ -108,9 +108,9 @@ static int clk_audio_pll_frac_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_audio_pll_pad_enable(struct clk *clk)
+static int clk_audio_pll_pad_enable(struct clk_hw *hw)
 {
-	struct clk_audio_pad *apad_ck = to_clk_audio_pad(clk);
+	struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
 
 	regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL1,
 			   AT91_PMC_AUDIO_PLL_QDPAD_MASK,
@@ -121,9 +121,9 @@ static int clk_audio_pll_pad_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_audio_pll_pmc_enable(struct clk *clk)
+static int clk_audio_pll_pmc_enable(struct clk_hw *hw)
 {
-	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(clk);
+	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
 
 	regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
 			   AT91_PMC_AUDIO_PLL_PMCEN |
@@ -133,9 +133,9 @@ static int clk_audio_pll_pmc_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_audio_pll_frac_disable(struct clk *clk)
+static void clk_audio_pll_frac_disable(struct clk_hw *hw)
 {
-	struct clk_audio_frac *frac = to_clk_audio_frac(clk);
+	struct clk_audio_frac *frac = to_clk_audio_frac(hw);
 
 	regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
 			   AT91_PMC_AUDIO_PLL_PLLEN, 0);
@@ -144,17 +144,17 @@ static void clk_audio_pll_frac_disable(struct clk *clk)
 			   AT91_PMC_AUDIO_PLL_RESETN, 0);
 }
 
-static void clk_audio_pll_pad_disable(struct clk *clk)
+static void clk_audio_pll_pad_disable(struct clk_hw *hw)
 {
-	struct clk_audio_pad *apad_ck = to_clk_audio_pad(clk);
+	struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
 
 	regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0,
 			   AT91_PMC_AUDIO_PLL_PADEN, 0);
 }
 
-static void clk_audio_pll_pmc_disable(struct clk *clk)
+static void clk_audio_pll_pmc_disable(struct clk_hw *hw)
 {
-	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(clk);
+	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
 
 	regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
 			   AT91_PMC_AUDIO_PLL_PMCEN, 0);
@@ -174,10 +174,10 @@ static unsigned long clk_audio_pll_fout(unsigned long parent_rate,
 	return parent_rate * (nd + 1) + fr;
 }
 
-static unsigned long clk_audio_pll_frac_recalc_rate(struct clk *clk,
+static unsigned long clk_audio_pll_frac_recalc_rate(struct clk_hw *hw,
 						    unsigned long parent_rate)
 {
-	struct clk_audio_frac *frac = to_clk_audio_frac(clk);
+	struct clk_audio_frac *frac = to_clk_audio_frac(hw);
 	unsigned long fout;
 
 	fout = clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr);
@@ -188,10 +188,10 @@ static unsigned long clk_audio_pll_frac_recalc_rate(struct clk *clk,
 	return fout;
 }
 
-static unsigned long clk_audio_pll_pad_recalc_rate(struct clk *clk,
+static unsigned long clk_audio_pll_pad_recalc_rate(struct clk_hw *hw,
 						   unsigned long parent_rate)
 {
-	struct clk_audio_pad *apad_ck = to_clk_audio_pad(clk);
+	struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
 	unsigned long apad_rate = 0;
 
 	if (apad_ck->qdaudio && apad_ck->div)
@@ -203,10 +203,10 @@ static unsigned long clk_audio_pll_pad_recalc_rate(struct clk *clk,
 	return apad_rate;
 }
 
-static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk *clk,
+static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk_hw *hw,
 						   unsigned long parent_rate)
 {
-	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(clk);
+	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
 	unsigned long apmc_rate = 0;
 
 	apmc_rate = parent_rate / (apmc_ck->qdpmc + 1);
@@ -245,10 +245,10 @@ static int clk_audio_pll_frac_compute_frac(unsigned long rate,
 	return 0;
 }
 
-static long clk_audio_pll_pad_round_rate(struct clk *clk, unsigned long rate,
+static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
 					 unsigned long *parent_rate)
 {
-	struct clk *pclk = clk_get_parent(clk);
+	struct clk *pclk = clk_get_parent(clk_hw_to_clk(hw));
 	long best_rate = -EINVAL;
 	unsigned long best_parent_rate;
 	unsigned long tmp_qd;
@@ -296,9 +296,10 @@ static long clk_audio_pll_pad_round_rate(struct clk *clk, unsigned long rate,
 	return best_rate;
 }
 
-static long clk_audio_pll_pmc_round_rate(struct clk *clk, unsigned long rate,
+static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
 					 unsigned long *parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct clk *pclk = clk_get_parent(clk);
 	long best_rate = -EINVAL;
 	unsigned long best_parent_rate = 0;
@@ -336,10 +337,10 @@ static long clk_audio_pll_pmc_round_rate(struct clk *clk, unsigned long rate,
 	return best_rate;
 }
 
-static int clk_audio_pll_frac_set_rate(struct clk *clk, unsigned long rate,
+static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
-	struct clk_audio_frac *frac = to_clk_audio_frac(clk);
+	struct clk_audio_frac *frac = to_clk_audio_frac(hw);
 	unsigned long fracr, nd;
 	int ret;
 
@@ -359,10 +360,10 @@ static int clk_audio_pll_frac_set_rate(struct clk *clk, unsigned long rate,
 	return 0;
 }
 
-static int clk_audio_pll_pad_set_rate(struct clk *clk, unsigned long rate,
+static int clk_audio_pll_pad_set_rate(struct clk_hw *hw, unsigned long rate,
 				      unsigned long parent_rate)
 {
-	struct clk_audio_pad *apad_ck = to_clk_audio_pad(clk);
+	struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
 	u8 tmp_div;
 
 	pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__,
@@ -383,10 +384,10 @@ static int clk_audio_pll_pad_set_rate(struct clk *clk, unsigned long rate,
 	return 0;
 }
 
-static int clk_audio_pll_pmc_set_rate(struct clk *clk, unsigned long rate,
+static int clk_audio_pll_pmc_set_rate(struct clk_hw *hw, unsigned long rate,
 				      unsigned long parent_rate)
 {
-	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(clk);
+	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
 
 	if (!rate)
 		return -EINVAL;
@@ -433,22 +434,22 @@ at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
 	if (!frac_ck)
 		return ERR_PTR(-ENOMEM);
 
-	frac_ck->clk.name = name;
-	frac_ck->clk.ops = &audio_pll_frac_ops;
+	frac_ck->hw.clk.name = name;
+	frac_ck->hw.clk.ops = &audio_pll_frac_ops;
 	frac_ck->parent_name = parent_name;
-	frac_ck->clk.parent_names = &frac_ck->parent_name;
-	frac_ck->clk.num_parents = 1;
+	frac_ck->hw.clk.parent_names = &frac_ck->parent_name;
+	frac_ck->hw.clk.num_parents = 1;
 	/* frac_ck->clk.flags = CLK_SET_RATE_GATE; */
 
 	frac_ck->regmap = regmap;
 
-	ret = bclk_register(&frac_ck->clk);
+	ret = bclk_register(&frac_ck->hw.clk);
 	if (ret) {
 		kfree(frac_ck);
 		return ERR_PTR(ret);
 	}
 
-	return &frac_ck->clk;
+	return &frac_ck->hw.clk;
 }
 
 struct clk * __init
@@ -462,23 +463,23 @@ at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
 	if (!apad_ck)
 		return ERR_PTR(-ENOMEM);
 
-	apad_ck->clk.name = name;
-	apad_ck->clk.ops = &audio_pll_pad_ops;
+	apad_ck->hw.clk.name = name;
+	apad_ck->hw.clk.ops = &audio_pll_pad_ops;
 	apad_ck->parent_name = parent_name;
-	apad_ck->clk.parent_names = &apad_ck->parent_name;
-	apad_ck->clk.num_parents = 1;
+	apad_ck->hw.clk.parent_names = &apad_ck->parent_name;
+	apad_ck->hw.clk.num_parents = 1;
 	/* apad_ck->clk.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
 		CLK_SET_RATE_PARENT; */
 
 	apad_ck->regmap = regmap;
 
-	ret = bclk_register(&apad_ck->clk);
+	ret = bclk_register(&apad_ck->hw.clk);
 	if (ret) {
 		kfree(apad_ck);
 		return ERR_PTR(ret);
 	}
 
-	return &apad_ck->clk;
+	return &apad_ck->hw.clk;
 }
 
 struct clk * __init
@@ -492,21 +493,21 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
 	if (!apmc_ck)
 		return ERR_PTR(-ENOMEM);
 
-	apmc_ck->clk.name = name;
-	apmc_ck->clk.ops = &audio_pll_pmc_ops;
+	apmc_ck->hw.clk.name = name;
+	apmc_ck->hw.clk.ops = &audio_pll_pmc_ops;
 	apmc_ck->parent_name = parent_name;
-	apmc_ck->clk.parent_names = &apmc_ck->parent_name;
-	apmc_ck->clk.num_parents = 1;
+	apmc_ck->hw.clk.parent_names = &apmc_ck->parent_name;
+	apmc_ck->hw.clk.num_parents = 1;
 	/* apmc_ck.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
 		CLK_SET_RATE_PARENT; */
 
 	apmc_ck->regmap = regmap;
 
-	ret = bclk_register(&apmc_ck->clk);
+	ret = bclk_register(&apmc_ck->hw.clk);
 	if (ret) {
 		kfree(apmc_ck);
 		return ERR_PTR(ret);
 	}
 
-	return &apmc_ck->clk;
+	return &apmc_ck->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 23d193f9dd..628ff407d9 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -23,7 +23,7 @@
 #define GCK_INDEX_DT_AUDIO_PLL	5
 
 struct clk_generated {
-	struct clk hw;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	struct clk_range range;
 	u32 id;
@@ -33,10 +33,10 @@ struct clk_generated {
 	bool audio_pll_allowed;
 };
 
-#define to_clk_generated(hw) \
-	container_of(hw, struct clk_generated, hw)
+#define to_clk_generated(_hw) \
+	container_of(_hw, struct clk_generated, hw)
 
-static int clk_generated_enable(struct clk *hw)
+static int clk_generated_enable(struct clk_hw *hw)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
 
@@ -55,7 +55,7 @@ static int clk_generated_enable(struct clk *hw)
 	return 0;
 }
 
-static void clk_generated_disable(struct clk *hw)
+static void clk_generated_disable(struct clk_hw *hw)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
 
@@ -66,7 +66,7 @@ static void clk_generated_disable(struct clk *hw)
 			   gck->layout->cmd);
 }
 
-static int clk_generated_is_enabled(struct clk *hw)
+static int clk_generated_is_enabled(struct clk_hw *hw)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
 	unsigned int status;
@@ -79,7 +79,7 @@ static int clk_generated_is_enabled(struct clk *hw)
 }
 
 static unsigned long
-clk_generated_recalc_rate(struct clk *hw,
+clk_generated_recalc_rate(struct clk_hw *hw,
 			  unsigned long parent_rate)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
@@ -88,18 +88,18 @@ clk_generated_recalc_rate(struct clk *hw,
 }
 
 /* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
-static int clk_generated_set_parent(struct clk *hw, u8 index)
+static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
 
-	if (index >= clk_get_num_parents(hw))
+	if (index >= clk_get_num_parents(clk_hw_to_clk(hw)))
 		return -EINVAL;
 
 	gck->parent_id = index;
 	return 0;
 }
 
-static int clk_generated_get_parent(struct clk *hw)
+static int clk_generated_get_parent(struct clk_hw *hw)
 {
 	struct clk_generated *gck = to_clk_generated(hw);
 
@@ -107,7 +107,7 @@ static int clk_generated_get_parent(struct clk *hw)
 }
 
 /* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
-static int clk_generated_set_rate(struct clk *hw,
+static int clk_generated_set_rate(struct clk_hw *hw,
 				  unsigned long rate,
 				  unsigned long parent_rate)
 {
@@ -168,7 +168,7 @@ at91_clk_register_generated(struct regmap *regmap,
 {
 	size_t parents_array_size;
 	struct clk_generated *gck;
-	struct clk *hw;
+	struct clk *clk;
 	int ret;
 
 	gck = kzalloc(sizeof(*gck), GFP_KERNEL);
@@ -176,12 +176,12 @@ at91_clk_register_generated(struct regmap *regmap,
 		return ERR_PTR(-ENOMEM);
 
 	gck->id = id;
-	gck->hw.name = name;
-	gck->hw.ops = &generated_ops;
+	gck->hw.clk.name = name;
+	gck->hw.clk.ops = &generated_ops;
 
-	parents_array_size = num_parents * sizeof(gck->hw.parent_names[0]);
-	gck->hw.parent_names = xmemdup(parent_names, parents_array_size);
-	gck->hw.num_parents = num_parents;
+	parents_array_size = num_parents * sizeof(gck->hw.clk.parent_names[0]);
+	gck->hw.clk.parent_names = xmemdup(parent_names, parents_array_size);
+	gck->hw.clk.num_parents = num_parents;
 
 	/* gck->hw.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | CLK_SET_PARENT; */
 	gck->regmap = regmap;
@@ -190,14 +190,14 @@ at91_clk_register_generated(struct regmap *regmap,
 	gck->layout = layout;
 
 	clk_generated_startup(gck);
-	hw = &gck->hw;
-	ret = bclk_register(&gck->hw);
+	clk = &gck->hw.clk;
+	ret = bclk_register(&gck->hw.clk);
 	if (ret) {
 		kfree(gck);
-		hw = ERR_PTR(ret);
+		clk = ERR_PTR(ret);
 	} else {
 		pmc_register_id(id);
 	}
 
-	return hw;
+	return clk;
 }
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 1bcd30be75..b2c5007cf7 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -20,14 +20,14 @@
 #define H32MX_MAX_FREQ	90000000
 
 struct clk_sama5d4_h32mx {
-	struct clk hw;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent;
 };
 
-#define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw)
+#define to_clk_sama5d4_h32mx(_hw) container_of(_hw, struct clk_sama5d4_h32mx, hw)
 
-static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk *hw,
+static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
 	struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
@@ -42,7 +42,7 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk *hw,
 	return parent_rate;
 }
 
-static long clk_sama5d4_h32mx_round_rate(struct clk *hw, unsigned long rate,
+static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long *parent_rate)
 {
 	unsigned long div;
@@ -59,7 +59,7 @@ static long clk_sama5d4_h32mx_round_rate(struct clk *hw, unsigned long rate,
 	return *parent_rate;
 }
 
-static int clk_sama5d4_h32mx_set_rate(struct clk *hw, unsigned long rate,
+static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
 				    unsigned long parent_rate)
 {
 	struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
@@ -95,19 +95,19 @@ at91_clk_register_h32mx(struct regmap *regmap, const char *name,
 		return ERR_PTR(-ENOMEM);
 
 	h32mxclk->parent = parent_name;
-	h32mxclk->hw.name = name;
-	h32mxclk->hw.ops = &h32mx_ops;
-	h32mxclk->hw.parent_names = &h32mxclk->parent;
-	h32mxclk->hw.num_parents = 1;
+	h32mxclk->hw.clk.name = name;
+	h32mxclk->hw.clk.ops = &h32mx_ops;
+	h32mxclk->hw.clk.parent_names = &h32mxclk->parent;
+	h32mxclk->hw.clk.num_parents = 1;
 	/* h32mxclk.hw.flags = CLK_SET_RATE_GATE; */
 
 	h32mxclk->regmap = regmap;
 
-	ret = bclk_register(&h32mxclk->hw);
+	ret = bclk_register(&h32mxclk->hw.clk);
 	if (ret) {
 		kfree(h32mxclk);
 		return ERR_PTR(ret);
 	}
 
-	return &h32mxclk->hw;
+	return &h32mxclk->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c
index 6e3d1e8f59..510ea24bbc 100644
--- a/drivers/clk/at91/clk-i2s-mux.c
+++ b/drivers/clk/at91/clk-i2s-mux.c
@@ -21,17 +21,17 @@
 #include "pmc.h"
 
 struct clk_i2s_mux {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 bus_id;
 	const char *parent_names[];
 };
 
-#define to_clk_i2s_mux(clk) container_of(clk, struct clk_i2s_mux, clk)
+#define to_clk_i2s_mux(_hw) container_of(_hw, struct clk_i2s_mux, hw)
 
-static int clk_i2s_mux_get_parent(struct clk *clk)
+static int clk_i2s_mux_get_parent(struct clk_hw *hw)
 {
-	struct clk_i2s_mux *mux = to_clk_i2s_mux(clk);
+	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);
 	u32 val;
 
 	regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val);
@@ -39,9 +39,9 @@ static int clk_i2s_mux_get_parent(struct clk *clk)
 	return (val & BIT(mux->bus_id)) >> mux->bus_id;
 }
 
-static int clk_i2s_mux_set_parent(struct clk *clk, u8 index)
+static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_i2s_mux *mux = to_clk_i2s_mux(clk);
+	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);
 
 	return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL,
 				  BIT(mux->bus_id), index << mux->bus_id);
@@ -66,21 +66,21 @@ at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
 	if (!i2s_ck)
 		return ERR_PTR(-ENOMEM);
 
-	i2s_ck->clk.name = name;
-	i2s_ck->clk.ops = &clk_i2s_mux_ops;
+	i2s_ck->hw.clk.name = name;
+	i2s_ck->hw.clk.ops = &clk_i2s_mux_ops;
 	memcpy(i2s_ck->parent_names, parent_names,
 	       num_parents * sizeof(i2s_ck->parent_names[0]));
-	i2s_ck->clk.parent_names = &i2s_ck->parent_names[0];
-	i2s_ck->clk.num_parents = num_parents;
+	i2s_ck->hw.clk.parent_names = &i2s_ck->parent_names[0];
+	i2s_ck->hw.clk.num_parents = num_parents;
 
 	i2s_ck->bus_id = bus_id;
 	i2s_ck->regmap = regmap;
 
-	ret = bclk_register(&i2s_ck->clk);
+	ret = bclk_register(&i2s_ck->hw.clk);
 	if (ret) {
 		kfree(i2s_ck);
 		return ERR_PTR(ret);
 	}
 
-	return &i2s_ck->clk;
+	return &i2s_ck->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 74c26a1516..38e72d6538 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -26,36 +26,36 @@
 					AT91_PMC_OSCBYPASS)) ? 1 : 0)
 
 struct clk_main_osc {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent;
 };
 
-#define to_clk_main_osc(clk) container_of(clk, struct clk_main_osc, clk)
+#define to_clk_main_osc(_hw) container_of(_hw, struct clk_main_osc, hw)
 
 struct clk_main_rc_osc {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	unsigned long frequency;
 };
 
-#define to_clk_main_rc_osc(clk) container_of(clk, struct clk_main_rc_osc, clk)
+#define to_clk_main_rc_osc(_hw) container_of(_hw, struct clk_main_rc_osc, hw)
 
 struct clk_rm9200_main {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent;
 };
 
-#define to_clk_rm9200_main(clk) container_of(clk, struct clk_rm9200_main, clk)
+#define to_clk_rm9200_main(_hw) container_of(_hw, struct clk_rm9200_main, hw)
 
 struct clk_sam9x5_main {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 parent;
 };
 
-#define to_clk_sam9x5_main(clk) container_of(clk, struct clk_sam9x5_main, clk)
+#define to_clk_sam9x5_main(_hw) container_of(_hw, struct clk_sam9x5_main, hw)
 
 static inline bool clk_main_osc_ready(struct regmap *regmap)
 {
@@ -66,9 +66,9 @@ static inline bool clk_main_osc_ready(struct regmap *regmap)
 	return status & AT91_PMC_MOSCS;
 }
 
-static int clk_main_osc_enable(struct clk *clk)
+static int clk_main_osc_enable(struct clk_hw *hw)
 {
-	struct clk_main_osc *osc = to_clk_main_osc(clk);
+	struct clk_main_osc *osc = to_clk_main_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	u32 tmp;
 
@@ -89,9 +89,9 @@ static int clk_main_osc_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_main_osc_disable(struct clk *clk)
+static void clk_main_osc_disable(struct clk_hw *hw)
 {
-	struct clk_main_osc *osc = to_clk_main_osc(clk);
+	struct clk_main_osc *osc = to_clk_main_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	u32 tmp;
 
@@ -106,9 +106,9 @@ static void clk_main_osc_disable(struct clk *clk)
 	regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
 }
 
-static int clk_main_osc_is_enabled(struct clk *clk)
+static int clk_main_osc_is_enabled(struct clk_hw *hw)
 {
-	struct clk_main_osc *osc = to_clk_main_osc(clk);
+	struct clk_main_osc *osc = to_clk_main_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	u32 tmp, status;
 
@@ -142,10 +142,10 @@ at91_clk_register_main_osc(struct regmap *regmap,
 	osc = xzalloc(sizeof(*osc));
 
 	osc->parent = parent_name;
-	osc->clk.name = name;
-	osc->clk.ops = &main_osc_ops;
-	osc->clk.parent_names = &osc->parent;
-	osc->clk.num_parents = 1;
+	osc->hw.clk.name = name;
+	osc->hw.clk.ops = &main_osc_ops;
+	osc->hw.clk.parent_names = &osc->parent;
+	osc->hw.clk.num_parents = 1;
 	osc->regmap = regmap;
 
 	if (bypass)
@@ -154,13 +154,13 @@ at91_clk_register_main_osc(struct regmap *regmap,
 				  AT91_PMC_MOSCEN,
 				  AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 
-	ret = bclk_register(&osc->clk);
+	ret = bclk_register(&osc->hw.clk);
 	if (ret) {
 		free(osc);
 		return ERR_PTR(ret);
 	}
 
-	return &osc->clk;
+	return &osc->hw.clk;
 }
 
 static bool clk_main_rc_osc_ready(struct regmap *regmap)
@@ -172,9 +172,9 @@ static bool clk_main_rc_osc_ready(struct regmap *regmap)
 	return status & AT91_PMC_MOSCRCS;
 }
 
-static int clk_main_rc_osc_enable(struct clk *clk)
+static int clk_main_rc_osc_enable(struct clk_hw *hw)
 {
-	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(clk);
+	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	unsigned int mor;
 
@@ -191,9 +191,9 @@ static int clk_main_rc_osc_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_main_rc_osc_disable(struct clk *clk)
+static void clk_main_rc_osc_disable(struct clk_hw *hw)
 {
-	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(clk);
+	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	unsigned int mor;
 
@@ -206,9 +206,9 @@ static void clk_main_rc_osc_disable(struct clk *clk)
 			  MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
 }
 
-static int clk_main_rc_osc_is_enabled(struct clk *clk)
+static int clk_main_rc_osc_is_enabled(struct clk_hw *hw)
 {
-	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(clk);
+	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 	struct regmap *regmap = osc->regmap;
 	unsigned int mor, status;
 
@@ -218,10 +218,10 @@ static int clk_main_rc_osc_is_enabled(struct clk *clk)
 	return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
 }
 
-static unsigned long clk_main_rc_osc_recalc_rate(struct clk *clk,
+static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
-	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(clk);
+	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 
 	return osc->frequency;
 }
@@ -246,21 +246,21 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
 
 	osc = xzalloc(sizeof(*osc));
 
-	osc->clk.name = name;
-	osc->clk.ops = &main_rc_osc_ops;
-	osc->clk.parent_names = NULL;
-	osc->clk.num_parents = 0;
+	osc->hw.clk.name = name;
+	osc->hw.clk.ops = &main_rc_osc_ops;
+	osc->hw.clk.parent_names = NULL;
+	osc->hw.clk.num_parents = 0;
 
 	osc->regmap = regmap;
 	osc->frequency = frequency;
 
-	ret = bclk_register(&osc->clk);
+	ret = bclk_register(&osc->hw.clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
 	}
 
-	return &osc->clk;
+	return &osc->hw.clk;
 }
 
 static int clk_main_probe_frequency(struct regmap *regmap)
@@ -293,16 +293,16 @@ static unsigned long clk_main_recalc_rate(struct regmap *regmap,
 	return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
 }
 
-static int clk_rm9200_main_enable(struct clk *clk)
+static int clk_rm9200_main_enable(struct clk_hw *hw)
 {
-	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(clk);
+	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 
 	return clk_main_probe_frequency(clkmain->regmap);
 }
 
-static int clk_rm9200_main_is_enabled(struct clk *clk)
+static int clk_rm9200_main_is_enabled(struct clk_hw *hw)
 {
-	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(clk);
+	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 	unsigned int status;
 
 	regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
@@ -310,10 +310,10 @@ static int clk_rm9200_main_is_enabled(struct clk *clk)
 	return status & AT91_PMC_MAINRDY ? 1 : 0;
 }
 
-static unsigned long clk_rm9200_main_recalc_rate(struct clk *clk,
+static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
-	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(clk);
+	struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 
 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 }
@@ -341,19 +341,19 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
 	clkmain = xzalloc(sizeof(*clkmain));
 
 	clkmain->parent = parent_name;
-	clkmain->clk.name = name;
-	clkmain->clk.ops = &rm9200_main_ops;
-	clkmain->clk.parent_names = &clkmain->parent;
-	clkmain->clk.num_parents = 1;
+	clkmain->hw.clk.name = name;
+	clkmain->hw.clk.ops = &rm9200_main_ops;
+	clkmain->hw.clk.parent_names = &clkmain->parent;
+	clkmain->hw.clk.num_parents = 1;
 	clkmain->regmap = regmap;
 
-	ret = bclk_register(&clkmain->clk);
+	ret = bclk_register(&clkmain->hw.clk);
 	if (ret) {
 		kfree(clkmain);
 		return ERR_PTR(ret);
 	}
 
-	return &clkmain->clk;
+	return &clkmain->hw.clk;
 }
 
 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
@@ -365,9 +365,9 @@ static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 	return status & AT91_PMC_MOSCSELS ? 1 : 0;
 }
 
-static int clk_sam9x5_main_enable(struct clk *clk)
+static int clk_sam9x5_main_enable(struct clk_hw *hw)
 {
-	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(clk);
+	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 	struct regmap *regmap = clkmain->regmap;
 
 	while (!clk_sam9x5_main_ready(regmap))
@@ -376,24 +376,24 @@ static int clk_sam9x5_main_enable(struct clk *clk)
 	return clk_main_probe_frequency(regmap);
 }
 
-static int clk_sam9x5_main_is_enabled(struct clk *clk)
+static int clk_sam9x5_main_is_enabled(struct clk_hw *hw)
 {
-	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(clk);
+	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 
 	return clk_sam9x5_main_ready(clkmain->regmap);
 }
 
-static unsigned long clk_sam9x5_main_recalc_rate(struct clk *clk,
+static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
-	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(clk);
+	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 
 	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 }
 
-static int clk_sam9x5_main_set_parent(struct clk *clk, u8 index)
+static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(clk);
+	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 	struct regmap *regmap = clkmain->regmap;
 	unsigned int tmp;
 
@@ -414,9 +414,9 @@ static int clk_sam9x5_main_set_parent(struct clk *clk, u8 index)
 	return 0;
 }
 
-static int clk_sam9x5_main_get_parent(struct clk *clk)
+static int clk_sam9x5_main_get_parent(struct clk_hw *hw)
 {
-	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(clk);
+	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 	unsigned int status;
 
 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
@@ -451,11 +451,11 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
 
 	clkmain = xzalloc(sizeof(*clkmain));
 
-	clkmain->clk.name = name;
-	clkmain->clk.ops = &sam9x5_main_ops;
-	parents_array_size = num_parents * sizeof (clkmain->clk.parent_names[0]);
-	clkmain->clk.parent_names = xmemdup(parent_names, parents_array_size);
-	clkmain->clk.num_parents = num_parents;
+	clkmain->hw.clk.name = name;
+	clkmain->hw.clk.ops = &sam9x5_main_ops;
+	parents_array_size = num_parents * sizeof (clkmain->hw.clk.parent_names[0]);
+	clkmain->hw.clk.parent_names = xmemdup(parent_names, parents_array_size);
+	clkmain->hw.clk.num_parents = num_parents;
 
 	/* init.flags = CLK_SET_PARENT_GATE; */
 
@@ -463,11 +463,11 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
 	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 	clkmain->parent = clk_main_parent_select(status);
 
-	ret = bclk_register(&clkmain->clk);
+	ret = bclk_register(&clkmain->hw.clk);
 	if (ret) {
 		kfree(clkmain);
 		return ERR_PTR(ret);
 	}
 
-	return &clkmain->clk;
+	return &clkmain->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index dcdc4fceda..3e4836b667 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -18,10 +18,10 @@
 #define MASTER_DIV_SHIFT	8
 #define MASTER_DIV_MASK		0x3
 
-#define to_clk_master(clk) container_of(clk, struct clk_master, clk)
+#define to_clk_master(_hw) container_of(_hw, struct clk_master, hw)
 
 struct clk_master {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const struct clk_master_layout *layout;
 	const struct clk_master_characteristics *characteristics;
@@ -38,9 +38,9 @@ static inline bool clk_master_ready(struct regmap *regmap)
 	return status & AT91_PMC_MCKRDY ? 1 : 0;
 }
 
-static int clk_master_enable(struct clk *clk)
+static int clk_master_enable(struct clk_hw *hw)
 {
-	struct clk_master *master = to_clk_master(clk);
+	struct clk_master *master = to_clk_master(hw);
 
 	while (!clk_master_ready(master->regmap))
 		barrier();
@@ -48,20 +48,20 @@ static int clk_master_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_master_is_enabled(struct clk *clk)
+static int clk_master_is_enabled(struct clk_hw *hw)
 {
-	struct clk_master *master = to_clk_master(clk);
+	struct clk_master *master = to_clk_master(hw);
 
 	return clk_master_ready(master->regmap);
 }
 
-static unsigned long clk_master_recalc_rate(struct clk *clk,
+static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
 	u8 pres;
 	u8 div;
 	unsigned long rate = parent_rate;
-	struct clk_master *master = to_clk_master(clk);
+	struct clk_master *master = to_clk_master(hw);
 	const struct clk_master_layout *layout = master->layout;
 	const struct clk_master_characteristics *characteristics =
 						master->characteristics;
@@ -88,9 +88,9 @@ static unsigned long clk_master_recalc_rate(struct clk *clk,
 	return rate;
 }
 
-static int clk_master_get_parent(struct clk *clk)
+static int clk_master_get_parent(struct clk_hw *hw)
 {
-	struct clk_master *master = to_clk_master(clk);
+	struct clk_master *master = to_clk_master(hw);
 	unsigned int mckr;
 
 	regmap_read(master->regmap, master->layout->offset, &mckr);
@@ -121,23 +121,23 @@ at91_clk_register_master(struct regmap *regmap,
 
 	master = xzalloc(struct_size(master, parents, num_parents));
 
-	master->clk.name = name;
-	master->clk.ops = &master_ops;
+	master->hw.clk.name = name;
+	master->hw.clk.ops = &master_ops;
 	memcpy(master->parents, parent_names, parent_names_size);
-	master->clk.parent_names = master->parents;
-	master->clk.num_parents = num_parents;
+	master->hw.clk.parent_names = master->parents;
+	master->hw.clk.num_parents = num_parents;
 
 	master->layout = layout;
 	master->characteristics = characteristics;
 	master->regmap = regmap;
 
-	ret = bclk_register(&master->clk);
+	ret = bclk_register(&master->hw.clk);
 	if (ret) {
 		kfree(master);
 		return ERR_PTR(ret);
 	}
 
-	return &master->clk;
+	return &master->hw.clk;
 }
 
 
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 055c8c3b98..c768947647 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -23,16 +23,16 @@
 #define PERIPHERAL_MAX_SHIFT	3
 
 struct clk_peripheral {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u32 id;
 	const char *parent;
 };
 
-#define to_clk_peripheral(clk) container_of(clk, struct clk_peripheral, clk)
+#define to_clk_peripheral(_hw) container_of(_hw, struct clk_peripheral, hw)
 
 struct clk_sam9x5_peripheral {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	struct clk_range range;
 	u32 id;
@@ -42,12 +42,12 @@ struct clk_sam9x5_peripheral {
 	const char *parent;
 };
 
-#define to_clk_sam9x5_peripheral(clk) \
-	container_of(clk, struct clk_sam9x5_peripheral, clk)
+#define to_clk_sam9x5_peripheral(_hw) \
+	container_of(_hw, struct clk_sam9x5_peripheral, hw)
 
-static int clk_peripheral_enable(struct clk *clk)
+static int clk_peripheral_enable(struct clk_hw *hw)
 {
-	struct clk_peripheral *periph = to_clk_peripheral(clk);
+	struct clk_peripheral *periph = to_clk_peripheral(hw);
 	int offset = AT91_PMC_PCER;
 	u32 id = periph->id;
 
@@ -60,9 +60,9 @@ static int clk_peripheral_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_peripheral_disable(struct clk *clk)
+static void clk_peripheral_disable(struct clk_hw *hw)
 {
-	struct clk_peripheral *periph = to_clk_peripheral(clk);
+	struct clk_peripheral *periph = to_clk_peripheral(hw);
 	int offset = AT91_PMC_PCDR;
 	u32 id = periph->id;
 
@@ -73,9 +73,9 @@ static void clk_peripheral_disable(struct clk *clk)
 	regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id));
 }
 
-static int clk_peripheral_is_enabled(struct clk *clk)
+static int clk_peripheral_is_enabled(struct clk_hw *hw)
 {
-	struct clk_peripheral *periph = to_clk_peripheral(clk);
+	struct clk_peripheral *periph = to_clk_peripheral(hw);
 	int offset = AT91_PMC_PCSR;
 	unsigned int status;
 	u32 id = periph->id;
@@ -107,25 +107,25 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
 
 	periph = xzalloc(sizeof(*periph));
 
-	periph->clk.name = name;
-	periph->clk.ops = &peripheral_ops;
+	periph->hw.clk.name = name;
+	periph->hw.clk.ops = &peripheral_ops;
 
 	if (parent_name) {
 		periph->parent = parent_name;
-		periph->clk.parent_names = &periph->parent;
-		periph->clk.num_parents = 1;
+		periph->hw.clk.parent_names = &periph->parent;
+		periph->hw.clk.num_parents = 1;
 	}
 
 	periph->id = id;
 	periph->regmap = regmap;
 
-	ret = bclk_register(&periph->clk);
+	ret = bclk_register(&periph->hw.clk);
 	if (ret) {
 		kfree(periph);
 		return ERR_PTR(ret);
 	}
 
-	return &periph->clk;
+	return &periph->hw.clk;
 }
 
 static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
@@ -138,7 +138,7 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
 		return;
 
 	if (periph->range.max) {
-		parent = clk_get_parent(&periph->clk);
+		parent = clk_get_parent(&periph->hw.clk);
 		parent_rate = clk_get_rate(parent);
 		if (!parent_rate)
 			return;
@@ -153,9 +153,9 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph)
 	periph->div = shift;
 }
 
-static int clk_sam9x5_peripheral_enable(struct clk *clk)
+static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
 {
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 
 	if (periph->id < PERIPHERAL_ID_MIN)
 		return 0;
@@ -172,9 +172,9 @@ static int clk_sam9x5_peripheral_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_sam9x5_peripheral_disable(struct clk *clk)
+static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
 {
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 
 	if (periph->id < PERIPHERAL_ID_MIN)
 		return;
@@ -186,9 +186,9 @@ static void clk_sam9x5_peripheral_disable(struct clk *clk)
 			  periph->layout->cmd);
 }
 
-static int clk_sam9x5_peripheral_is_enabled(struct clk *clk)
+static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
 {
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 	unsigned int status;
 
 	if (periph->id < PERIPHERAL_ID_MIN)
@@ -202,10 +202,10 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk *clk)
 }
 
 static unsigned long
-clk_sam9x5_peripheral_recalc_rate(struct clk *clk,
+clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
 				  unsigned long parent_rate)
 {
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 	unsigned int status;
 
 	if (periph->id < PERIPHERAL_ID_MIN)
@@ -225,7 +225,7 @@ clk_sam9x5_peripheral_recalc_rate(struct clk *clk,
 	return parent_rate >> periph->div;
 }
 
-static long clk_sam9x5_peripheral_round_rate(struct clk *clk,
+static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
 					     unsigned long rate,
 					     unsigned long *parent_rate)
 {
@@ -234,7 +234,7 @@ static long clk_sam9x5_peripheral_round_rate(struct clk *clk,
 	unsigned long best_diff;
 	unsigned long cur_rate = *parent_rate;
 	unsigned long cur_diff;
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 
 	if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max)
 		return *parent_rate;
@@ -271,12 +271,12 @@ static long clk_sam9x5_peripheral_round_rate(struct clk *clk,
 	return best_rate;
 }
 
-static int clk_sam9x5_peripheral_set_rate(struct clk *clk,
+static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw,
 					  unsigned long rate,
 					  unsigned long parent_rate)
 {
 	int shift;
-	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+	struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
 	if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) {
 		if (parent_rate == rate)
 			return 0;
@@ -321,13 +321,13 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
 
 	periph = xzalloc(sizeof(*periph));
 
-	periph->clk.name = name;
-	periph->clk.ops = &sam9x5_peripheral_ops;
+	periph->hw.clk.name = name;
+	periph->hw.clk.ops = &sam9x5_peripheral_ops;
 
 	if (parent_name) {
 		periph->parent = parent_name;
-		periph->clk.parent_names = &periph->parent;
-		periph->clk.num_parents = 1;
+		periph->hw.clk.parent_names = &periph->parent;
+		periph->hw.clk.num_parents = 1;
 	}
 
 	periph->id = id;
@@ -338,7 +338,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
 	periph->layout = layout;
 	periph->range = *range;
 
-	ret = bclk_register(&periph->clk);
+	ret = bclk_register(&periph->hw.clk);
 	if (ret) {
 		kfree(periph);
 		return ERR_PTR(ret);
@@ -347,5 +347,5 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
 	clk_sam9x5_peripheral_autodiv(periph);
 	pmc_register_id(id);
 
-	return &periph->clk;
+	return &periph->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
index 04d915706a..d8ea566f49 100644
--- a/drivers/clk/at91/clk-pll.c
+++ b/drivers/clk/at91/clk-pll.c
@@ -31,10 +31,10 @@
 #define PLL_OUT_SHIFT		14
 #define PLL_MAX_ID		1
 
-#define to_clk_pll(clk) container_of(clk, struct clk_pll, clk)
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
 
 struct clk_pll {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 id;
 	u8 div;
@@ -54,9 +54,9 @@ static inline bool clk_pll_ready(struct regmap *regmap, int id)
 	return status & PLL_STATUS_MASK(id) ? 1 : 0;
 }
 
-static int clk_pll_enable(struct clk *clk)
+static int clk_pll_enable(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 	struct regmap *regmap = pll->regmap;
 	const struct clk_pll_layout *layout = pll->layout;
 	const struct clk_pll_characteristics *characteristics =
@@ -97,25 +97,25 @@ static int clk_pll_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_pll_is_enabled(struct clk *clk)
+static int clk_pll_is_enabled(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	return clk_pll_ready(pll->regmap, pll->id);
 }
 
-static void clk_pll_disable(struct clk *clk)
+static void clk_pll_disable(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 	unsigned int mask = pll->layout->pllr_mask;
 
 	regmap_write_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask);
 }
 
-static unsigned long clk_pll_recalc_rate(struct clk *clk,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	if (!pll->div || !pll->mul)
 		return 0;
@@ -233,19 +233,19 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
 	return bestrate;
 }
 
-static long clk_pll_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *parent_rate)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	return clk_pll_get_best_div_mul(pll, rate, *parent_rate,
 					NULL, NULL, NULL);
 }
 
-static int clk_pll_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 	long ret;
 	u32 div;
 	u32 mul;
@@ -289,10 +289,10 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
 	pll = xzalloc(sizeof(*pll));
 
 	pll->parent = parent_name;
-	pll->clk.name = name;
-	pll->clk.ops = &pll_ops;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.name = name;
+	pll->hw.clk.ops = &pll_ops;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
 	/* init.flags = CLK_SET_RATE_GATE; */
 
@@ -304,13 +304,13 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
 	pll->div = PLL_DIV(pllr);
 	pll->mul = PLL_MUL(pllr, layout);
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
 
 
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
index 3a8b0dc9ee..2830b16722 100644
--- a/drivers/clk/at91/clk-plldiv.c
+++ b/drivers/clk/at91/clk-plldiv.c
@@ -14,18 +14,18 @@
 
 #include "pmc.h"
 
-#define to_clk_plldiv(hw) container_of(clk, struct clk_plldiv, clk)
+#define to_clk_plldiv(_hw) container_of(_hw, struct clk_plldiv, hw)
 
 struct clk_plldiv {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent;
 };
 
-static unsigned long clk_plldiv_recalc_rate(struct clk *clk,
+static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
-	struct clk_plldiv *plldiv = to_clk_plldiv(clk);
+	struct clk_plldiv *plldiv = to_clk_plldiv(hw);
 	unsigned int mckr;
 
 	regmap_read(plldiv->regmap, AT91_PMC_MCKR, &mckr);
@@ -36,7 +36,7 @@ static unsigned long clk_plldiv_recalc_rate(struct clk *clk,
 	return parent_rate;
 }
 
-static long clk_plldiv_round_rate(struct clk *clk, unsigned long rate,
+static long clk_plldiv_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *parent_rate)
 {
 	unsigned long div;
@@ -53,10 +53,10 @@ static long clk_plldiv_round_rate(struct clk *clk, unsigned long rate,
 	return *parent_rate;
 }
 
-static int clk_plldiv_set_rate(struct clk *clk, unsigned long rate,
+static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate)
 {
-	struct clk_plldiv *plldiv = to_clk_plldiv(clk);
+	struct clk_plldiv *plldiv = to_clk_plldiv(hw);
 
 	if ((parent_rate != rate) && (parent_rate / 2 != rate))
 		return -EINVAL;
@@ -82,24 +82,24 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
 
 	plldiv = xzalloc(sizeof(*plldiv));
 
-	plldiv->clk.name = name;
-	plldiv->clk.ops  = &plldiv_ops;
+	plldiv->hw.clk.name = name;
+	plldiv->hw.clk.ops  = &plldiv_ops;
 
 	if (parent_name) {
 		plldiv->parent = parent_name;
-		plldiv->clk.parent_names = &plldiv->parent;
-		plldiv->clk.num_parents = 1;
+		plldiv->hw.clk.parent_names = &plldiv->parent;
+		plldiv->hw.clk.num_parents = 1;
 	}
 
 	/* init.flags = CLK_SET_RATE_GATE; */
 
 	plldiv->regmap = regmap;
 
-	ret = bclk_register(&plldiv->clk);
+	ret = bclk_register(&plldiv->hw.clk);
 	if (ret) {
 		kfree(plldiv);
 		return ERR_PTR(ret);
 	}
 
-	return &plldiv->clk;
+	return &plldiv->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 70a8ca6d93..ec53f1addd 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -22,19 +22,19 @@
 #define PROG_MAX_RM9200_CSS	3
 
 struct clk_programmable {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 id;
 	const struct clk_programmable_layout *layout;
 	const char *parent_names[];
 };
 
-#define to_clk_programmable(clk) container_of(clk, struct clk_programmable, clk)
+#define to_clk_programmable(_hw) container_of(_hw, struct clk_programmable, hw)
 
-static unsigned long clk_programmable_recalc_rate(struct clk *clk,
+static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
-	struct clk_programmable *prog = to_clk_programmable(clk);
+	struct clk_programmable *prog = to_clk_programmable(hw);
 	const struct clk_programmable_layout *layout = prog->layout;
 	unsigned int pckr;
 	unsigned long rate;
@@ -49,9 +49,9 @@ static unsigned long clk_programmable_recalc_rate(struct clk *clk,
 	return rate;
 }
 
-static int clk_programmable_set_parent(struct clk *clk, u8 index)
+static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_programmable *prog = to_clk_programmable(clk);
+	struct clk_programmable *prog = to_clk_programmable(hw);
 	const struct clk_programmable_layout *layout = prog->layout;
 	unsigned int mask = layout->css_mask;
 	unsigned int pckr = index;
@@ -71,9 +71,9 @@ static int clk_programmable_set_parent(struct clk *clk, u8 index)
 	return 0;
 }
 
-static int clk_programmable_get_parent(struct clk *clk)
+static int clk_programmable_get_parent(struct clk_hw *hw)
 {
-	struct clk_programmable *prog = to_clk_programmable(clk);
+	struct clk_programmable *prog = to_clk_programmable(hw);
 	const struct clk_programmable_layout *layout = prog->layout;
 	unsigned int pckr;
 	u8 ret;
@@ -88,10 +88,10 @@ static int clk_programmable_get_parent(struct clk *clk)
 	return ret;
 }
 
-static int clk_programmable_set_rate(struct clk *clk, unsigned long rate,
+static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
-	struct clk_programmable *prog = to_clk_programmable(clk);
+	struct clk_programmable *prog = to_clk_programmable(hw);
 	const struct clk_programmable_layout *layout = prog->layout;
 	unsigned long div = parent_rate / rate;
 	int shift = 0;
@@ -144,19 +144,19 @@ at91_clk_register_programmable(struct regmap *regmap,
 	if (!prog)
 		return ERR_PTR(-ENOMEM);
 
-	prog->clk.name = name;
-	prog->clk.ops = &programmable_ops;
+	prog->hw.clk.name = name;
+	prog->hw.clk.ops = &programmable_ops;
 	memcpy(prog->parent_names, parent_names,
 	       num_parents * sizeof(prog->parent_names[0]));
-	prog->clk.parent_names = &prog->parent_names[0];
-	prog->clk.num_parents = num_parents;
+	prog->hw.clk.parent_names = &prog->parent_names[0];
+	prog->hw.clk.num_parents = num_parents;
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
 
 	prog->id = id;
 	prog->layout = layout;
 	prog->regmap = regmap;
 
-	ret = bclk_register(&prog->clk);
+	ret = bclk_register(&prog->hw.clk);
 	if (ret) {
 		kfree(prog);
 		return ERR_PTR(ret);
@@ -164,7 +164,7 @@ at91_clk_register_programmable(struct regmap *regmap,
 
 	pmc_register_pck(id);
 
-	return &prog->clk;
+	return &prog->hw.clk;
 }
 
 const struct clk_programmable_layout at91rm9200_programmable_layout = {
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index 91c6b62667..744c3833bb 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -55,7 +55,7 @@ struct sam9x60_pll {
 	const char *parent_name;
 };
 
-#define to_sam9x60_pll(clk) container_of(clk, struct sam9x60_pll, clk)
+#define to_sam9x60_pll(_hw) container_of(_hw->clk, struct sam9x60_pll, clk)
 
 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
 {
@@ -66,9 +66,9 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
 	return !!(status & BIT(id));
 }
 
-static int sam9x60_pll_enable(struct clk *clk)
+static int sam9x60_pll_enable(struct clk_hw *hw)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 	struct regmap *regmap = pll->regmap;
 	u8 div;
 	u16 mul;
@@ -127,16 +127,16 @@ static int sam9x60_pll_enable(struct clk *clk)
 	return 0;
 }
 
-static int sam9x60_pll_is_enabled(struct clk *clk)
+static int sam9x60_pll_is_enabled(struct clk_hw *hw)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 
 	return sam9x60_pll_ready(pll->regmap, pll->id);
 }
 
-static void sam9x60_pll_disable(struct clk *clk)
+static void sam9x60_pll_disable(struct clk_hw *hw)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 
 	regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
 
@@ -156,10 +156,10 @@ static void sam9x60_pll_disable(struct clk *clk)
 			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
 }
 
-static unsigned long sam9x60_pll_recalc_rate(struct clk *clk,
+static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 
 	return (parent_rate * (pll->mul + 1)) / (pll->div + 1);
 }
@@ -253,18 +253,18 @@ static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
 	return bestrate;
 }
 
-static long sam9x60_pll_round_rate(struct clk *clk, unsigned long rate,
+static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				   unsigned long *parent_rate)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 
 	return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false);
 }
 
-static int sam9x60_pll_set_rate(struct clk *clk, unsigned long rate,
+static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
-	struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
 
 	return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true);
 }
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index 1768f0ad5e..bc4285e4bf 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -18,16 +18,16 @@
 #include "pmc.h"
 
 struct clk_sam9260_slow {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent_names[];
 };
 
-#define to_clk_sam9260_slow(clk) container_of(clk, struct clk_sam9260_slow, clk)
+#define to_clk_sam9260_slow(_hw) container_of(_hw, struct clk_sam9260_slow, hw)
 
-static int clk_sam9260_slow_get_parent(struct clk *clk)
+static int clk_sam9260_slow_get_parent(struct clk_hw *hw)
 {
-	struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(clk);
+	struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
 	unsigned int status;
 
 	regmap_read(slowck->regmap, AT91_PMC_SR, &status);
@@ -55,19 +55,19 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
 		return ERR_PTR(-EINVAL);
 
 	slowck = xzalloc(struct_size(slowck, parent_names, num_parents));
-	slowck->clk.name = name;
-	slowck->clk.ops = &sam9260_slow_ops;
+	slowck->hw.clk.name = name;
+	slowck->hw.clk.ops = &sam9260_slow_ops;
 	memcpy(slowck->parent_names, parent_names,
 	       num_parents * sizeof(slowck->parent_names[0]));
-	slowck->clk.parent_names = slowck->parent_names;
-	slowck->clk.num_parents = num_parents;
+	slowck->hw.clk.parent_names = slowck->parent_names;
+	slowck->hw.clk.num_parents = num_parents;
 	slowck->regmap = regmap;
 
-	ret = bclk_register(&slowck->clk);
+	ret = bclk_register(&slowck->hw.clk);
 	if (ret) {
 		kfree(slowck);
 		return ERR_PTR(ret);
 	}
 
-	return &slowck->clk;
+	return &slowck->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index ad376d03c9..6df698637c 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -21,18 +21,18 @@
 #define SMD_MAX_DIV		0xf
 
 struct at91sam9x5_clk_smd {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	const char *parent_names[];
 };
 
-#define to_at91sam9x5_clk_smd(clk) \
-	container_of(clk, struct at91sam9x5_clk_smd, clk)
+#define to_at91sam9x5_clk_smd(_hw) \
+	container_of(_hw, struct at91sam9x5_clk_smd, hw)
 
-static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk *clk,
+static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
 						    unsigned long parent_rate)
 {
-	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
 	unsigned int smdr;
 	u8 smddiv;
 
@@ -42,7 +42,7 @@ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk *clk,
 	return parent_rate / (smddiv + 1);
 }
 
-static long at91sam9x5_clk_smd_round_rate(struct clk *clk, unsigned long rate,
+static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate,
 					  unsigned long *parent_rate)
 {
 	unsigned long div;
@@ -64,9 +64,9 @@ static long at91sam9x5_clk_smd_round_rate(struct clk *clk, unsigned long rate,
 	return bestrate;
 }
 
-static int at91sam9x5_clk_smd_set_parent(struct clk *clk, u8 index)
+static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
 
 	if (index > 1)
 		return -EINVAL;
@@ -77,9 +77,9 @@ static int at91sam9x5_clk_smd_set_parent(struct clk *clk, u8 index)
 	return 0;
 }
 
-static int at91sam9x5_clk_smd_get_parent(struct clk *clk)
+static int at91sam9x5_clk_smd_get_parent(struct clk_hw *hw)
 {
-	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
 	unsigned int smdr;
 
 	regmap_read(smd->regmap, AT91_PMC_SMD, &smdr);
@@ -87,10 +87,10 @@ static int at91sam9x5_clk_smd_get_parent(struct clk *clk)
 	return smdr & AT91_PMC_SMDS;
 }
 
-static int at91sam9x5_clk_smd_set_rate(struct clk *clk, unsigned long rate,
+static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
-	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+	struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
 	unsigned long div = parent_rate / rate;
 
 	if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1))
@@ -118,20 +118,20 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
 	int ret;
 
 	smd = xzalloc(struct_size(smd, parent_names, num_parents));
-	smd->clk.name = name;
-	smd->clk.ops = &at91sam9x5_smd_ops;
+	smd->hw.clk.name = name;
+	smd->hw.clk.ops = &at91sam9x5_smd_ops;
 	memcpy(smd->parent_names, parent_names,
 	       num_parents * sizeof(smd->parent_names[0]));
-	smd->clk.parent_names = smd->parent_names;
-	smd->clk.num_parents = num_parents;
+	smd->hw.clk.parent_names = smd->parent_names;
+	smd->hw.clk.num_parents = num_parents;
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
 	smd->regmap = regmap;
 
-	ret = bclk_register(&smd->clk);
+	ret = bclk_register(&smd->hw.clk);
 	if (ret) {
 		kfree(smd);
 		return ERR_PTR(ret);
 	}
 
-	return &smd->clk;
+	return &smd->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index db9d7b3d61..9a15d5b04a 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -17,9 +17,9 @@
 
 #define SYSTEM_MAX_NAME_SZ	32
 
-#define to_clk_system(clk) container_of(clk, struct clk_system, clk)
+#define to_clk_system(_hw) container_of(_hw, struct clk_system, hw)
 struct clk_system {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u8 id;
 	const char *parent_name;
@@ -39,9 +39,9 @@ static inline bool clk_system_ready(struct regmap *regmap, int id)
 	return status & (1 << id) ? 1 : 0;
 }
 
-static int clk_system_enable(struct clk *clk)
+static int clk_system_enable(struct clk_hw *hw)
 {
-	struct clk_system *sys = to_clk_system(clk);
+	struct clk_system *sys = to_clk_system(hw);
 
 	regmap_write(sys->regmap, AT91_PMC_SCER, 1 << sys->id);
 
@@ -54,16 +54,16 @@ static int clk_system_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_system_disable(struct clk *clk)
+static void clk_system_disable(struct clk_hw *hw)
 {
-	struct clk_system *sys = to_clk_system(clk);
+	struct clk_system *sys = to_clk_system(hw);
 
 	regmap_write(sys->regmap, AT91_PMC_SCDR, 1 << sys->id);
 }
 
-static int clk_system_is_enabled(struct clk *clk)
+static int clk_system_is_enabled(struct clk_hw *hw)
 {
-	struct clk_system *sys = to_clk_system(clk);
+	struct clk_system *sys = to_clk_system(hw);
 	unsigned int status;
 
 	regmap_read(sys->regmap, AT91_PMC_SCSR, &status);
@@ -96,20 +96,20 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
 		return ERR_PTR(-EINVAL);
 
 	sys = xzalloc(sizeof(*sys));
-	sys->clk.name = name;
-	sys->clk.ops = &system_ops;
+	sys->hw.clk.name = name;
+	sys->hw.clk.ops = &system_ops;
 	sys->parent_name = parent_name;
-	sys->clk.parent_names = &sys->parent_name;
-	sys->clk.num_parents = 1;
+	sys->hw.clk.parent_names = &sys->parent_name;
+	sys->hw.clk.num_parents = 1;
 	/* init.flags = CLK_SET_RATE_PARENT; */
 	sys->id = id;
 	sys->regmap = regmap;
 
-	ret = bclk_register(&sys->clk);
+	ret = bclk_register(&sys->hw.clk);
 	if (ret) {
 		kfree(sys);
 		return ERR_PTR(ret);
 	}
 
-	return &sys->clk;
+	return &sys->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index d60232f771..148befc8ac 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -27,30 +27,30 @@
 #define SAM9X60_USBS_MASK	GENMASK(1, 0)
 
 struct at91sam9x5_clk_usb {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u32 usbs_mask;
 	u8 num_parents;
 	const char *parent_names[];
 };
 
-#define to_at91sam9x5_clk_usb(clk) \
-	container_of(clk, struct at91sam9x5_clk_usb, clk)
+#define to_at91sam9x5_clk_usb(_hw) \
+	container_of(_hw, struct at91sam9x5_clk_usb, hw)
 
 struct at91rm9200_clk_usb {
-	struct clk clk;
+	struct clk_hw hw;
 	struct regmap *regmap;
 	u32 divisors[4];
 	const char *parent_name;
 };
 
-#define to_at91rm9200_clk_usb(clk) \
-	container_of(clk, struct at91rm9200_clk_usb, clk)
+#define to_at91rm9200_clk_usb(_hw) \
+	container_of(_hw, struct at91rm9200_clk_usb, hw)
 
-static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk *clk,
+static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
 						    unsigned long parent_rate)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 	unsigned int usbr;
 	u8 usbdiv;
 
@@ -60,9 +60,9 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk *clk,
 	return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
 }
 
-static int at91sam9x5_clk_usb_set_parent(struct clk *clk, u8 index)
+static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 
 	if (index >= usb->num_parents)
 		return -EINVAL;
@@ -72,9 +72,9 @@ static int at91sam9x5_clk_usb_set_parent(struct clk *clk, u8 index)
 	return 0;
 }
 
-static int at91sam9x5_clk_usb_get_parent(struct clk *clk)
+static int at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 	unsigned int usbr;
 
 	regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
@@ -82,10 +82,10 @@ static int at91sam9x5_clk_usb_get_parent(struct clk *clk)
 	return usbr & usb->usbs_mask;
 }
 
-static int at91sam9x5_clk_usb_set_rate(struct clk *clk, unsigned long rate,
+static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 	unsigned long div;
 
 	if (!rate)
@@ -108,9 +108,9 @@ static const struct clk_ops at91sam9x5_usb_ops = {
 	.set_rate = at91sam9x5_clk_usb_set_rate,
 };
 
-static int at91sam9n12_clk_usb_enable(struct clk *clk)
+static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 
 	regmap_write_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS,
 			  AT91_PMC_USBS);
@@ -118,16 +118,16 @@ static int at91sam9n12_clk_usb_enable(struct clk *clk)
 	return 0;
 }
 
-static void at91sam9n12_clk_usb_disable(struct clk *clk)
+static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 
 	regmap_write_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, 0);
 }
 
-static int at91sam9n12_clk_usb_is_enabled(struct clk *clk)
+static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
 {
-	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(clk);
+	struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
 	unsigned int usbr;
 
 	regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
@@ -152,26 +152,26 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
 	int ret;
 
 	usb = kzalloc(struct_size(usb, parent_names, num_parents), GFP_KERNEL);
-	usb->clk.name = name;
-	usb->clk.ops = &at91sam9x5_usb_ops;
+	usb->hw.clk.name = name;
+	usb->hw.clk.ops = &at91sam9x5_usb_ops;
 	memcpy(usb->parent_names, parent_names,
 	       num_parents * sizeof(usb->parent_names[0]));
-	usb->clk.parent_names = usb->parent_names;
-	usb->clk.num_parents = num_parents;
-	usb->clk.flags = CLK_SET_RATE_PARENT;
+	usb->hw.clk.parent_names = usb->parent_names;
+	usb->hw.clk.num_parents = num_parents;
+	usb->hw.clk.flags = CLK_SET_RATE_PARENT;
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | */
 	/* 	     CLK_SET_RATE_PARENT; */
 	usb->regmap = regmap;
 	usb->usbs_mask = usbs_mask;
 	usb->num_parents = num_parents;
 
-	ret = bclk_register(&usb->clk);
+	ret = bclk_register(&usb->hw.clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
 	}
 
-	return &usb->clk;
+	return &usb->hw.clk;
 }
 
 struct clk * __init
@@ -198,27 +198,27 @@ at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
 	int ret;
 
 	usb = xzalloc(sizeof(*usb));
-	usb->clk.name = name;
-	usb->clk.ops = &at91sam9n12_usb_ops;
+	usb->hw.clk.name = name;
+	usb->hw.clk.ops = &at91sam9n12_usb_ops;
 	usb->parent_names[0] = parent_name;
-	usb->clk.parent_names = &usb->parent_names[0];
-	usb->clk.num_parents = 1;
+	usb->hw.clk.parent_names = &usb->parent_names[0];
+	usb->hw.clk.num_parents = 1;
 	/* init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; */
 	usb->regmap = regmap;
 
-	ret = bclk_register(&usb->clk);
+	ret = bclk_register(&usb->hw.clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
 	}
 
-	return &usb->clk;
+	return &usb->hw.clk;
 }
 
-static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk *clk,
+static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
 						    unsigned long parent_rate)
 {
-	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(clk);
+	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
 	unsigned int pllbr;
 	u8 usbdiv;
 
@@ -231,11 +231,11 @@ static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk *clk,
 	return 0;
 }
 
-static long at91rm9200_clk_usb_round_rate(struct clk *clk, unsigned long rate,
+static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
 					  unsigned long *parent_rate)
 {
-	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(clk);
-	struct clk *parent = clk_get_parent(clk);
+	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
+	struct clk *parent = clk_get_parent(clk_hw_to_clk(hw));
 	unsigned long bestrate = 0;
 	int bestdiff = -1;
 	unsigned long tmprate;
@@ -272,11 +272,11 @@ static long at91rm9200_clk_usb_round_rate(struct clk *clk, unsigned long rate,
 	return bestrate;
 }
 
-static int at91rm9200_clk_usb_set_rate(struct clk *clk, unsigned long rate,
+static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
 	int i;
-	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(clk);
+	struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
 	unsigned long div;
 
 	if (!rate)
@@ -311,21 +311,21 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
 	int ret;
 
 	usb = xzalloc(sizeof(*usb));
-	usb->clk.name = name;
-	usb->clk.ops = &at91rm9200_usb_ops;
+	usb->hw.clk.name = name;
+	usb->hw.clk.ops = &at91rm9200_usb_ops;
 	usb->parent_name = parent_name;
-	usb->clk.parent_names = &usb->parent_name;
-	usb->clk.num_parents = 1;
+	usb->hw.clk.parent_names = &usb->parent_name;
+	usb->hw.clk.num_parents = 1;
 	/* init.flags = CLK_SET_RATE_PARENT; */
 
 	usb->regmap = regmap;
 	memcpy(usb->divisors, divisors, sizeof(usb->divisors));
 
-	ret = bclk_register(&usb->clk);
+	ret = bclk_register(&usb->hw.clk);
 	if (ret) {
 		kfree(usb);
 		return ERR_PTR(ret);
 	}
 
-	return &usb->clk;
+	return &usb->hw.clk;
 }
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index df3904e5a0..1389983bde 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -22,13 +22,13 @@
 #define UTMI_RATE      480000000
 
 struct clk_utmi {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	struct regmap *regmap_pmc;
 	struct regmap *regmap_sfr;
 };
 
-#define to_clk_utmi(clk) container_of(clk, struct clk_utmi, clk)
+#define to_clk_utmi(_hw) container_of(_hw, struct clk_utmi, hw)
 
 static inline bool clk_utmi_ready(struct regmap *regmap)
 {
@@ -39,10 +39,10 @@ static inline bool clk_utmi_ready(struct regmap *regmap)
 	return status & AT91_PMC_LOCKU;
 }
 
-static int clk_utmi_enable(struct clk *clk)
+static int clk_utmi_enable(struct clk_hw *hw)
 {
 	struct clk *hw_parent;
-	struct clk_utmi *utmi = to_clk_utmi(clk);
+	struct clk_utmi *utmi = to_clk_utmi(hw);
 	unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
 			    AT91_PMC_BIASEN;
 	unsigned int utmi_ref_clk_freq;
@@ -53,7 +53,7 @@ static int clk_utmi_enable(struct clk *clk)
 	 * FREQ field of the SFR_UTMICKTRIM register to generate properly
 	 * the utmi clock.
 	 */
-	hw_parent = clk_get_parent(clk);
+	hw_parent = clk_get_parent(clk_hw_to_clk(hw));
 	parent_rate = clk_get_rate(hw_parent);
 
 	switch (parent_rate) {
@@ -95,22 +95,22 @@ static int clk_utmi_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_utmi_is_enabled(struct clk *clk)
+static int clk_utmi_is_enabled(struct clk_hw *hw)
 {
-	struct clk_utmi *utmi = to_clk_utmi(clk);
+	struct clk_utmi *utmi = to_clk_utmi(hw);
 
 	return clk_utmi_ready(utmi->regmap_pmc);
 }
 
-static void clk_utmi_disable(struct clk *clk)
+static void clk_utmi_disable(struct clk_hw *hw)
 {
-	struct clk_utmi *utmi = to_clk_utmi(clk);
+	struct clk_utmi *utmi = to_clk_utmi(hw);
 
 	regmap_write_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
 			  AT91_PMC_UPLLEN, 0);
 }
 
-static unsigned long clk_utmi_recalc_rate(struct clk *clk,
+static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
 					  unsigned long parent_rate)
 {
 	/* UTMI clk rate is fixed */
@@ -133,13 +133,13 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
 
 	utmi = xzalloc(sizeof(*utmi));
 
-	utmi->clk.name = name;
-	utmi->clk.ops = &utmi_ops;
+	utmi->hw.clk.name = name;
+	utmi->hw.clk.ops = &utmi_ops;
 
 	if (parent_name) {
 		utmi->parent = parent_name;
-		utmi->clk.parent_names = &utmi->parent;
-		utmi->clk.num_parents = 1;
+		utmi->hw.clk.parent_names = &utmi->parent;
+		utmi->hw.clk.num_parents = 1;
 	}
 
 	/* utmi->clk.flags = CLK_SET_RATE_GATE; */
@@ -147,11 +147,11 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
 	utmi->regmap_pmc = regmap_pmc;
 	utmi->regmap_sfr = regmap_sfr;
 
-	ret = bclk_register(&utmi->clk);
+	ret = bclk_register(&utmi->hw.clk);
 	if (ret) {
 		kfree(utmi);
 		return ERR_PTR(ret);
 	}
 
-	return &utmi->clk;
+	return &utmi->hw.clk;
 }
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index bf55589c80..579fbf2479 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -34,17 +34,17 @@ struct clk_slow_bits {
 };
 
 struct clk_slow_osc {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *sckcr;
 	const struct clk_slow_bits *bits;
 	unsigned long startup_usec;
 	const char *parent_name;
 };
 
-#define to_clk_slow_osc(clk) container_of(clk, struct clk_slow_osc, clk)
+#define to_clk_slow_osc(_hw) container_of(_hw, struct clk_slow_osc, hw)
 
 struct clk_sama5d4_slow_osc {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *sckcr;
 	const struct clk_slow_bits *bits;
 	unsigned long startup_usec;
@@ -52,10 +52,10 @@ struct clk_sama5d4_slow_osc {
 	const char *parent_name;
 };
 
-#define to_clk_sama5d4_slow_osc(clk) container_of(clk, struct clk_sama5d4_slow_osc, clk)
+#define to_clk_sama5d4_slow_osc(_hw) container_of(_hw, struct clk_sama5d4_slow_osc, hw)
 
 struct clk_slow_rc_osc {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *sckcr;
 	const struct clk_slow_bits *bits;
 	unsigned long frequency;
@@ -63,21 +63,21 @@ struct clk_slow_rc_osc {
 	const char *parent_name;
 };
 
-#define to_clk_slow_rc_osc(clk) container_of(clk, struct clk_slow_rc_osc, clk)
+#define to_clk_slow_rc_osc(_hw) container_of(_hw, struct clk_slow_rc_osc, hw)
 
 struct clk_sam9x5_slow {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *sckcr;
 	const struct clk_slow_bits *bits;
 	u8 parent;
 	const char *parent_names[];
 };
 
-#define to_clk_sam9x5_slow(clk) container_of(clk, struct clk_sam9x5_slow, clk)
+#define to_clk_sam9x5_slow(_hw) container_of(_hw, struct clk_sam9x5_slow, hw)
 
-static int clk_slow_osc_enable(struct clk *clk)
+static int clk_slow_osc_enable(struct clk_hw *hw)
 {
-	struct clk_slow_osc *osc = to_clk_slow_osc(clk);
+	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
 	void __iomem *sckcr = osc->sckcr;
 	u32 tmp = readl(sckcr);
 
@@ -91,9 +91,9 @@ static int clk_slow_osc_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_slow_osc_disable(struct clk *clk)
+static void clk_slow_osc_disable(struct clk_hw *hw)
 {
-	struct clk_slow_osc *osc = to_clk_slow_osc(clk);
+	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
 	void __iomem *sckcr = osc->sckcr;
 	u32 tmp = readl(sckcr);
 
@@ -103,9 +103,9 @@ static void clk_slow_osc_disable(struct clk *clk)
 	writel(tmp & ~osc->bits->cr_osc32en, sckcr);
 }
 
-static int clk_slow_osc_is_enabled(struct clk *clk)
+static int clk_slow_osc_is_enabled(struct clk_hw *hw)
 {
-	struct clk_slow_osc *osc = to_clk_slow_osc(clk);
+	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
 	void __iomem *sckcr = osc->sckcr;
 	u32 tmp = readl(sckcr);
 
@@ -137,11 +137,11 @@ at91_clk_register_slow_osc(void __iomem *sckcr,
 
 	osc = xzalloc(sizeof(*osc));
 
-	osc->clk.name = name;
-	osc->clk.ops = &slow_osc_ops;
+	osc->hw.clk.name = name;
+	osc->hw.clk.ops = &slow_osc_ops;
 	osc->parent_name = parent_name;
-	osc->clk.parent_names = &osc->parent_name;
-	osc->clk.num_parents = 1;
+	osc->hw.clk.parent_names = &osc->parent_name;
+	osc->hw.clk.num_parents = 1;
 	/* osc->clk.flags = CLK_IGNORE_UNUSED; */
 
 	osc->sckcr = sckcr;
@@ -152,34 +152,34 @@ at91_clk_register_slow_osc(void __iomem *sckcr,
 		writel((readl(sckcr) & ~osc->bits->cr_osc32en) |
 					osc->bits->cr_osc32byp, sckcr);
 
-	ret = bclk_register(&osc->clk);
+	ret = bclk_register(&osc->hw.clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
 	}
 
-	return &osc->clk;
+	return &osc->hw.clk;
 }
 
 static void at91_clk_unregister_slow_osc(struct clk *clk)
 {
-	struct clk_slow_osc *osc = to_clk_slow_osc(clk);
+	struct clk_slow_osc *osc = to_clk_slow_osc(clk_to_clk_hw(clk));
 
 	clk_unregister(clk);
 	kfree(osc);
 }
 
-static unsigned long clk_slow_rc_osc_recalc_rate(struct clk *clk,
+static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
-	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk);
+	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
 
 	return osc->frequency;
 }
 
-static int clk_slow_rc_osc_enable(struct clk *clk)
+static int clk_slow_rc_osc_enable(struct clk_hw *hw)
 {
-	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk);
+	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
 	void __iomem *sckcr = osc->sckcr;
 
 	writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
@@ -189,17 +189,17 @@ static int clk_slow_rc_osc_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_slow_rc_osc_disable(struct clk *clk)
+static void clk_slow_rc_osc_disable(struct clk_hw *hw)
 {
-	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk);
+	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
 	void __iomem *sckcr = osc->sckcr;
 
 	writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr);
 }
 
-static int clk_slow_rc_osc_is_enabled(struct clk *clk)
+static int clk_slow_rc_osc_is_enabled(struct clk_hw *hw)
 {
-	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk);
+	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
 
 	return !!(readl(osc->sckcr) & osc->bits->cr_rcen);
 }
@@ -226,10 +226,10 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
 		return ERR_PTR(-EINVAL);
 
 	osc = xzalloc(sizeof(*osc));
-	osc->clk.name = name;
-	osc->clk.ops = &slow_rc_osc_ops;
-	osc->clk.parent_names = NULL;
-	osc->clk.num_parents = 0;
+	osc->hw.clk.name = name;
+	osc->hw.clk.ops = &slow_rc_osc_ops;
+	osc->hw.clk.parent_names = NULL;
+	osc->hw.clk.num_parents = 0;
 	/* init.flags = CLK_IGNORE_UNUSED; */
 
 	osc->sckcr = sckcr;
@@ -237,26 +237,26 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
 	osc->frequency = frequency;
 	osc->startup_usec = startup;
 
-	ret = bclk_register(&osc->clk);
+	ret = bclk_register(&osc->hw.clk);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
 	}
 
-	return &osc->clk;
+	return &osc->hw.clk;
 }
 
 static void at91_clk_unregister_slow_rc_osc(struct clk *clk)
 {
-	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk);
+	struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(clk_to_clk_hw(clk));
 
 	clk_unregister(clk);
 	kfree(osc);
 }
 
-static int clk_sam9x5_slow_set_parent(struct clk *clk, u8 index)
+static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(clk);
+	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
 	void __iomem *sckcr = slowck->sckcr;
 	u32 tmp;
 
@@ -281,9 +281,9 @@ static int clk_sam9x5_slow_set_parent(struct clk *clk, u8 index)
 	return 0;
 }
 
-static int clk_sam9x5_slow_get_parent(struct clk *clk)
+static int clk_sam9x5_slow_get_parent(struct clk_hw *hw)
 {
-	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(clk);
+	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
 
 	return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel);
 }
@@ -307,29 +307,29 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
 		return ERR_PTR(-EINVAL);
 
 	slowck = xzalloc(struct_size(slowck, parent_names, num_parents));
-	slowck->clk.name = name;
-	slowck->clk.ops = &sam9x5_slow_ops;
+	slowck->hw.clk.name = name;
+	slowck->hw.clk.ops = &sam9x5_slow_ops;
 
 	memcpy(slowck->parent_names, parent_names,
 	       num_parents * sizeof(slowck->parent_names[0]));
-	slowck->clk.parent_names = slowck->parent_names;
-	slowck->clk.num_parents = num_parents;
+	slowck->hw.clk.parent_names = slowck->parent_names;
+	slowck->hw.clk.num_parents = num_parents;
 	slowck->sckcr = sckcr;
 	slowck->bits = bits;
 	slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel);
 
-	ret = bclk_register(&slowck->clk);
+	ret = bclk_register(&slowck->hw.clk);
 	if (ret) {
 		kfree(slowck);
 		return ERR_PTR(ret);
 	}
 
-	return &slowck->clk;
+	return &slowck->hw.clk;
 }
 
 static void at91_clk_unregister_sam9x5_slow(struct clk *clk)
 {
-	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(clk);
+	struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(clk_to_clk_hw(clk));
 
 	clk_unregister(clk);
 	kfree(slowck);
@@ -505,9 +505,9 @@ unregister_slow_rc:
 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc",
 	       of_sam9x60_sckc_setup);
 
-static int clk_sama5d4_slow_osc_enable(struct clk *clk)
+static int clk_sama5d4_slow_osc_enable(struct clk_hw *hw)
 {
-	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(clk);
+	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
 
 	if (osc->prepared)
 		return 0;
@@ -527,9 +527,9 @@ static int clk_sama5d4_slow_osc_enable(struct clk *clk)
 	return 0;
 }
 
-static int clk_sama5d4_slow_osc_is_enabled(struct clk *clk)
+static int clk_sama5d4_slow_osc_is_enabled(struct clk_hw *hw)
 {
-	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(clk);
+	struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
 
 	return osc->prepared;
 }
@@ -560,10 +560,10 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np)
 
 	osc = xzalloc(sizeof(*osc));
 	osc->parent_name = of_clk_get_parent_name(np, 0);
-	osc->clk.name = parent_names[1];
-	osc->clk.ops = &sama5d4_slow_osc_ops;
-	osc->clk.parent_names = &osc->parent_name;
-	osc->clk.num_parents = 1;
+	osc->hw.clk.name = parent_names[1];
+	osc->hw.clk.ops = &sama5d4_slow_osc_ops;
+	osc->hw.clk.parent_names = &osc->parent_name;
+	osc->hw.clk.num_parents = 1;
 
 	/* osc->clk.flags = CLK_IGNORE_UNUSED; */
 
@@ -571,7 +571,7 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np)
 	osc->startup_usec = 1200000;
 	osc->bits = &at91sama5d4_bits;
 
-	ret = bclk_register(&osc->clk);
+	ret = bclk_register(&osc->hw.clk);
 	if (ret)
 		goto free_slow_osc_data;
 
@@ -590,7 +590,7 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np)
 unregister_slowck:
 	at91_clk_unregister_sam9x5_slow(slowck);
 unregister_slow_osc:
-	clk_unregister(&osc->clk);
+	clk_unregister(&osc->hw.clk);
 free_slow_osc_data:
 	kfree(osc);
 	clk_unregister(slow_rc);
diff --git a/drivers/clk/clk-ar933x.c b/drivers/clk/clk-ar933x.c
index 4727127aeb..c5e57f41ec 100644
--- a/drivers/clk/clk-ar933x.c
+++ b/drivers/clk/clk-ar933x.c
@@ -19,17 +19,17 @@ static struct clk *clks[ATH79_CLK_END];
 static struct clk_onecell_data clk_data;
 
 struct clk_ar933x {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *base;
 	u32 div_shift;
 	u32 div_mask;
 	const char *parent;
 };
 
-static unsigned long clk_ar933x_recalc_rate(struct clk *clk,
+static unsigned long clk_ar933x_recalc_rate(struct clk_hw *hw,
 	unsigned long parent_rate)
 {
-	struct clk_ar933x *f = container_of(clk, struct clk_ar933x, clk);
+	struct clk_ar933x *f = container_of(hw, struct clk_ar933x, hw);
 	unsigned long rate;
 	unsigned long freq;
 	u32 clock_ctrl;
@@ -79,14 +79,14 @@ static struct clk *clk_ar933x(const char *name, const char *parent,
 	f->div_shift = div_shift;
 	f->div_mask = div_mask;
 
-	f->clk.ops = &clk_ar933x_ops;
-	f->clk.name = name;
-	f->clk.parent_names = &f->parent;
-	f->clk.num_parents = 1;
+	f->hw.clk.ops = &clk_ar933x_ops;
+	f->hw.clk.name = name;
+	f->hw.clk.parent_names = &f->parent;
+	f->hw.clk.num_parents = 1;
 
-	bclk_register(&f->clk);
+	bclk_register(&f->hw.clk);
 
-	return &f->clk;
+	return &f->hw.clk;
 }
 
 static void ar933x_pll_init(void __iomem *base)
diff --git a/drivers/clk/clk-ar9344.c b/drivers/clk/clk-ar9344.c
index 1a25731fd5..d2f63f2608 100644
--- a/drivers/clk/clk-ar9344.c
+++ b/drivers/clk/clk-ar9344.c
@@ -35,17 +35,17 @@ static struct clk *clks[ATH79_CLK_END];
 static struct clk_onecell_data clk_data;
 
 struct clk_ar9344 {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *base;
 	u32 div_shift;
 	u32 div_mask;
 	const char *parent;
 };
 
-static unsigned long clk_ar9344_recalc_rate(struct clk *clk,
+static unsigned long clk_ar9344_recalc_rate(struct clk_hw *hw,
 	unsigned long parent_rate)
 {
-	struct clk_ar9344 *f = container_of(clk, struct clk_ar9344, clk);
+	struct clk_ar9344 *f = container_of(hw, struct clk_ar9344, hw);
 	int outdiv, refdiv, nint, nfrac;
 	int cpu_post_div;
 	u32 clock_ctrl;
@@ -84,14 +84,14 @@ static struct clk *clk_ar9344(const char *name, const char *parent,
 	f->div_shift = 0;
 	f->div_mask = 0;
 
-	f->clk.ops = &clk_ar9344_ops;
-	f->clk.name = name;
-	f->clk.parent_names = &f->parent;
-	f->clk.num_parents = 1;
+	f->hw.clk.ops = &clk_ar9344_ops;
+	f->hw.clk.name = name;
+	f->hw.clk.parent_names = &f->parent;
+	f->hw.clk.num_parents = 1;
 
-	bclk_register(&f->clk);
+	bclk_register(&f->hw.clk);
 
-	return &f->clk;
+	return &f->hw.clk;
 }
 
 static void ar9344_pll_init(void __iomem *base)
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 1eb1eea68e..3ed628c919 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -12,85 +12,93 @@
 #include <linux/err.h>
 
 struct clk_composite {
-	struct clk	clk;
+	struct clk_hw	hw;
 
 	struct clk	*mux_clk;
 	struct clk	*rate_clk;
 	struct clk	*gate_clk;
 };
 
-#define to_clk_composite(_clk) container_of(_clk, struct clk_composite, clk)
+#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
 
-static int clk_composite_get_parent(struct clk *clk)
+static int clk_composite_get_parent(struct clk_hw *hw)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *mux_clk = composite->mux_clk;
+	struct clk_hw *mux_hw = clk_to_clk_hw(mux_clk);
 
-	return mux_clk ? mux_clk->ops->get_parent(mux_clk) : 0;
+	return mux_clk ? mux_clk->ops->get_parent(mux_hw) : 0;
 }
 
-static int clk_composite_set_parent(struct clk *clk, u8 index)
+static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *mux_clk = composite->mux_clk;
+	struct clk_hw *mux_hw = clk_to_clk_hw(mux_clk);
 
-	return mux_clk ? mux_clk->ops->set_parent(mux_clk, index) : 0;
+	return mux_clk ? mux_clk->ops->set_parent(mux_hw, index) : 0;
 }
 
-static unsigned long clk_composite_recalc_rate(struct clk *clk,
+static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *rate_clk = composite->rate_clk;
+	struct clk_hw *rate_hw = clk_to_clk_hw(rate_clk);
 
 	if (rate_clk)
-		return rate_clk->ops->recalc_rate(rate_clk, parent_rate);
+		return rate_clk->ops->recalc_rate(rate_hw, parent_rate);
 
 	return parent_rate;
 }
 
-static long clk_composite_round_rate(struct clk *clk, unsigned long rate,
+static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *prate)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *rate_clk = composite->rate_clk;
+	struct clk_hw *rate_hw = clk_to_clk_hw(rate_clk);
 
-	return rate_clk ? rate_clk->ops->round_rate(rate_clk, rate, prate) : 0;
+	return rate_clk ? rate_clk->ops->round_rate(rate_hw, rate, prate) : 0;
 }
 
-static int clk_composite_set_rate(struct clk *clk, unsigned long rate,
+static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *rate_clk = composite->rate_clk;
+	struct clk_hw *rate_hw = clk_to_clk_hw(rate_clk);
 
 	return rate_clk ?
-		rate_clk->ops->set_rate(rate_clk, rate, parent_rate) : 0;
+		rate_clk->ops->set_rate(rate_hw, rate, parent_rate) : 0;
 }
 
-static int clk_composite_is_enabled(struct clk *clk)
+static int clk_composite_is_enabled(struct clk_hw *hw)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *gate_clk = composite->gate_clk;
+	struct clk_hw *gate_hw = clk_to_clk_hw(gate_clk);
 
-	return gate_clk ? gate_clk->ops->is_enabled(gate_clk) : 0;
+	return gate_clk ? gate_clk->ops->is_enabled(gate_hw) : 0;
 }
 
-static int clk_composite_enable(struct clk *clk)
+static int clk_composite_enable(struct clk_hw *hw)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *gate_clk = composite->gate_clk;
+	struct clk_hw *gate_hw = clk_to_clk_hw(gate_clk);
 
-	return gate_clk ? gate_clk->ops->enable(gate_clk) : 0;
+	return gate_clk ? gate_clk->ops->enable(gate_hw) : 0;
 }
 
-static void clk_composite_disable(struct clk *clk)
+static void clk_composite_disable(struct clk_hw *hw)
 {
-	struct clk_composite *composite = to_clk_composite(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
 	struct clk *gate_clk = composite->gate_clk;
+	struct clk_hw *gate_hw = clk_to_clk_hw(gate_clk);
 
 	if (gate_clk)
-		gate_clk->ops->disable(gate_clk);
+		gate_clk->ops->disable(gate_hw);
 }
 
 static struct clk_ops clk_composite_ops = {
@@ -116,20 +124,20 @@ struct clk *clk_register_composite(const char *name,
 
 	composite = xzalloc(sizeof(*composite));
 
-	composite->clk.name = name;
-	composite->clk.ops = &clk_composite_ops;
-	composite->clk.flags = flags;
-	composite->clk.parent_names = parent_names;
-	composite->clk.num_parents = num_parents;
+	composite->hw.clk.name = name;
+	composite->hw.clk.ops = &clk_composite_ops;
+	composite->hw.clk.flags = flags;
+	composite->hw.clk.parent_names = parent_names;
+	composite->hw.clk.num_parents = num_parents;
 	composite->mux_clk = mux_clk;
 	composite->rate_clk = rate_clk;
 	composite->gate_clk = gate_clk;
 
-	ret = bclk_register(&composite->clk);
+	ret = bclk_register(&composite->hw.clk);
 	if (ret)
 		goto err;
 
-	return &composite->clk;
+	return &composite->hw.clk;
 
 err:
 	kfree(composite);
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 3acce64042..edbba941b7 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -92,10 +92,11 @@ unsigned long divider_recalc_rate(struct clk *clk, unsigned long parent_rate,
 	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
 }
 
-static unsigned long clk_divider_recalc_rate(struct clk *clk,
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
 	unsigned int val;
 
 	val = readl(divider->reg) >> divider->shift;
@@ -233,13 +234,14 @@ long divider_round_rate(struct clk *clk, unsigned long rate,
 	return DIV_ROUND_UP(*prate, div);
 }
 
-static long clk_divider_round_rate(struct clk *clk, unsigned long rate,
+static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct clk_divider *divider = to_clk_divider(hw);
 
 	if (divider->flags & CLK_DIVIDER_READ_ONLY)
-		return clk_divider_recalc_rate(clk, *prate);
+		return clk_divider_recalc_rate(hw, *prate);
 
 	return divider_round_rate(clk, rate, prate, divider->table,
 				  divider->width, divider->flags);
@@ -261,10 +263,11 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
 	return min_t(unsigned int, value, clk_div_mask(width));
 }
 
-static int clk_divider_set_rate(struct clk *clk, unsigned long rate,
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct clk_divider *divider = to_clk_divider(hw);
 	unsigned int value;
 	u32 val;
 
@@ -310,18 +313,19 @@ struct clk *clk_divider_alloc(const char *name, const char *parent,
 	div->width = width;
 	div->parent = parent;
 	div->flags = div_flags;
-	div->clk.ops = &clk_divider_ops;
-	div->clk.name = name;
-	div->clk.flags = clk_flags;
-	div->clk.parent_names = &div->parent;
-	div->clk.num_parents = 1;
+	div->hw.clk.ops = &clk_divider_ops;
+	div->hw.clk.name = name;
+	div->hw.clk.flags = clk_flags;
+	div->hw.clk.parent_names = &div->parent;
+	div->hw.clk.num_parents = 1;
 
-	return &div->clk;
+	return &div->hw.clk;
 }
 
 void clk_divider_free(struct clk *clk)
 {
-	struct clk_divider *d =  container_of(clk, struct clk_divider, clk);
+	struct clk_hw *hw = clk_to_clk_hw(clk);
+	struct clk_divider *d = to_clk_divider(hw);
 
 	free(d);
 }
@@ -350,12 +354,15 @@ struct clk *clk_divider_one_based(const char *name, const char *parent,
 {
 	struct clk_divider *div;
 	struct clk *clk;
+	struct clk_hw *hw;
 
 	clk = clk_divider(name, parent, clk_flags, reg, shift, width, div_flags);
 	if (IS_ERR(clk))
 		return clk;
 
-	div = container_of(clk, struct clk_divider, clk);
+	hw = clk_to_clk_hw(clk);
+	div = to_clk_divider(hw);
+
 	div->flags |= CLK_DIVIDER_ONE_BASED;
 
 	return clk;
@@ -375,11 +382,11 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 	div->width = width;
 	div->parent = parent;
 	div->flags = div_flags;
-	div->clk.ops = &clk_divider_ops;
-	div->clk.name = name;
-	div->clk.flags = clk_flags;
-	div->clk.parent_names = &div->parent;
-	div->clk.num_parents = 1;
+	div->hw.clk.ops = &clk_divider_ops;
+	div->hw.clk.name = name;
+	div->hw.clk.flags = clk_flags;
+	div->hw.clk.parent_names = &div->parent;
+	div->hw.clk.num_parents = 1;
 	div->table = table;
 
 	for (clkt = div->table; clkt->div; clkt++) {
@@ -390,11 +397,11 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 		div->table_size++;
 	}
 
-	ret = bclk_register(&div->clk);
+	ret = bclk_register(&div->hw.clk);
 	if (ret) {
 		free(div);
 		return ERR_PTR(ret);
 	}
 
-	return &div->clk;
+	return &div->hw.clk;
 }
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index ce6fe1cce7..506c4aea74 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -11,24 +11,30 @@
 #include <linux/err.h>
 
 struct clk_fixed_factor {
-	struct clk clk;
+	struct clk_hw hw;
 	int mult;
 	int div;
 	const char *parent;
 };
 
-static unsigned long clk_fixed_factor_recalc_rate(struct clk *clk,
+static inline struct clk_fixed_factor *to_clk_fixed_factor(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_fixed_factor, hw);
+}
+
+static unsigned long clk_fixed_factor_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_fixed_factor *f = container_of(clk, struct clk_fixed_factor, clk);
+	struct clk_fixed_factor *f = to_clk_fixed_factor(hw);
 
 	return (parent_rate / f->div) * f->mult;
 }
 
-static long clk_factor_round_rate(struct clk *clk, unsigned long rate,
+static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long *prate)
 {
-	struct clk_fixed_factor *fix = container_of(clk, struct clk_fixed_factor, clk);
+	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
 
 	if (clk->flags & CLK_SET_RATE_PARENT) {
 		unsigned long best_parent;
@@ -40,10 +46,11 @@ static long clk_factor_round_rate(struct clk *clk, unsigned long rate,
 	return (*prate / fix->div) * fix->mult;
 }
 
-static int clk_factor_set_rate(struct clk *clk, unsigned long rate,
+static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_fixed_factor *fix = container_of(clk, struct clk_fixed_factor, clk);
+	struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
 
 	if (clk->flags & CLK_SET_RATE_PARENT) {
 		return clk_set_rate(clk_get_parent(clk), rate * fix->div / fix->mult);
@@ -67,19 +74,19 @@ struct clk *clk_fixed_factor(const char *name,
 	f->mult = mult;
 	f->div = div;
 	f->parent = parent;
-	f->clk.ops = &clk_fixed_factor_ops;
-	f->clk.name = name;
-	f->clk.flags = flags;
-	f->clk.parent_names = &f->parent;
-	f->clk.num_parents = 1;
+	f->hw.clk.ops = &clk_fixed_factor_ops;
+	f->hw.clk.name = name;
+	f->hw.clk.flags = flags;
+	f->hw.clk.parent_names = &f->parent;
+	f->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&f->clk);
+	ret = bclk_register(&f->hw.clk);
 	if (ret) {
 		free(f);
 		return ERR_PTR(ret);
 	}
 
-	return &f->clk;
+	return &f->hw.clk;
 }
 
 /**
diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c
index e628b4e4e6..b961c382ec 100644
--- a/drivers/clk/clk-fixed.c
+++ b/drivers/clk/clk-fixed.c
@@ -10,14 +10,14 @@
 #include <linux/err.h>
 
 struct clk_fixed {
-	struct clk clk;
+	struct clk_hw hw;
 	unsigned long rate;
 };
 
-static unsigned long clk_fixed_recalc_rate(struct clk *clk,
+static unsigned long clk_fixed_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_fixed *fix = container_of(clk, struct clk_fixed, clk);
+	struct clk_fixed *fix = container_of(hw, struct clk_fixed, hw);
 
 	return fix->rate;
 }
@@ -36,27 +36,27 @@ struct clk *clk_register_fixed_rate(const char *name,
 	int ret;
 
 	fix->rate = rate;
-	fix->clk.ops = &clk_fixed_ops;
-	fix->clk.name = name;
-	fix->clk.flags = flags;
+	fix->hw.clk.ops = &clk_fixed_ops;
+	fix->hw.clk.name = name;
+	fix->hw.clk.flags = flags;
 
 	if (parent_name) {
 		parent_names = kzalloc(sizeof(const char *), GFP_KERNEL);
 		if (!parent_names)
 			return ERR_PTR(-ENOMEM);
 
-		fix->clk.parent_names = parent_names;
-		fix->clk.num_parents = 1;
+		fix->hw.clk.parent_names = parent_names;
+		fix->hw.clk.num_parents = 1;
 	}
 
-	ret = bclk_register(&fix->clk);
+	ret = bclk_register(&fix->hw.clk);
 	if (ret) {
 		free(parent_names);
 		free(fix);
 		return ERR_PTR(ret);
 	}
 
-	return &fix->clk;
+	return &fix->hw.clk;
 }
 
 /**
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 6955666127..65abf84b40 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -15,10 +15,10 @@
 #include <linux/math64.h>
 #include <linux/barebox-wrapper.h>
 
-#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, clk)
+#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
 
 struct clk_fractional_divider {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*reg;
 	u8		mshift;
 	u32		mmask;
@@ -27,7 +27,7 @@ struct clk_fractional_divider {
 	u8		flags;
 };
 
-static unsigned long clk_fd_recalc_rate(struct clk *hw,
+static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 					unsigned long parent_rate)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
@@ -45,7 +45,7 @@ static unsigned long clk_fd_recalc_rate(struct clk *hw,
 	return ret;
 }
 
-static long clk_fd_round_rate(struct clk *hw, unsigned long rate,
+static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
 			      unsigned long *prate)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
@@ -65,7 +65,7 @@ static long clk_fd_round_rate(struct clk *hw, unsigned long rate,
 	return rate;
 }
 
-static int clk_fd_set_rate(struct clk *hw, unsigned long rate,
+static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
 			   unsigned long parent_rate)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
@@ -107,18 +107,18 @@ struct clk *clk_fractional_divider_alloc(
 	fd->nshift = nshift;
 	fd->nmask = (BIT(nwidth) - 1) << nshift;
 	fd->flags = clk_divider_flags;
-	fd->clk.name = name;
-	fd->clk.ops = &clk_fractional_divider_ops;
-	fd->clk.flags = flags;
-	fd->clk.parent_names = parent_name ? &parent_name : NULL;
-	fd->clk.num_parents = parent_name ? 1 : 0;
+	fd->hw.clk.name = name;
+	fd->hw.clk.ops = &clk_fractional_divider_ops;
+	fd->hw.clk.flags = flags;
+	fd->hw.clk.parent_names = parent_name ? &parent_name : NULL;
+	fd->hw.clk.num_parents = parent_name ? 1 : 0;
 
-	return &fd->clk;
+	return &fd->hw.clk;
 }
 
 void clk_fractional_divider_free(struct clk *clk_fd)
 {
-	struct clk_fractional_divider *fd = to_clk_fd(clk_fd);
+	struct clk_fractional_divider *fd = to_clk_fd(clk_to_clk_hw(clk_fd));
 
 	free(fd);
 }
diff --git a/drivers/clk/clk-gate-shared.c b/drivers/clk/clk-gate-shared.c
index b5a1365568..069f6975b1 100644
--- a/drivers/clk/clk-gate-shared.c
+++ b/drivers/clk/clk-gate-shared.c
@@ -11,13 +11,13 @@
 #include <linux/err.h>
 
 struct clk_gate_shared {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	const char *companion_gate;
 	struct clk *companion_clk;
 };
 
-#define to_clk_gate_shared(_clk) container_of(_clk, struct clk_gate_shared, clk)
+#define to_clk_gate_shared(_hw) container_of(_hw, struct clk_gate_shared, hw)
 
 static struct clk *lookup_companion(struct clk_gate_shared *g)
 {
@@ -30,23 +30,23 @@ static struct clk *lookup_companion(struct clk_gate_shared *g)
 	return g->companion_clk;
 }
 
-static int clk_gate_shared_enable(struct clk *clk)
+static int clk_gate_shared_enable(struct clk_hw *hw)
 {
-	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+	struct clk_gate_shared *g = to_clk_gate_shared(hw);
 
 	return clk_enable(lookup_companion(g));
 }
 
-static void clk_gate_shared_disable(struct clk *clk)
+static void clk_gate_shared_disable(struct clk_hw *hw)
 {
-	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+	struct clk_gate_shared *g = to_clk_gate_shared(hw);
 
 	clk_disable(lookup_companion(g));
 }
 
-static int clk_gate_shared_is_enabled(struct clk *clk)
+static int clk_gate_shared_is_enabled(struct clk_hw *hw)
 {
-	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+	struct clk_gate_shared *g = to_clk_gate_shared(hw);
 
 	return clk_is_enabled(lookup_companion(g));
 }
@@ -67,18 +67,19 @@ static struct clk *clk_gate_shared_alloc(const char *name, const char *parent,
 	g->parent = parent;
 	g->companion_gate = companion;
 	g->companion_clk = ERR_PTR(-EINVAL);
-	g->clk.ops = &clk_gate_shared_ops;
-	g->clk.name = name;
-	g->clk.flags = flags;
-	g->clk.parent_names = &g->parent;
-	g->clk.num_parents = 1;
+	g->hw.clk.ops = &clk_gate_shared_ops;
+	g->hw.clk.name = name;
+	g->hw.clk.flags = flags;
+	g->hw.clk.parent_names = &g->parent;
+	g->hw.clk.num_parents = 1;
 
-	return &g->clk;
+	return &g->hw.clk;
 }
 
 static void clk_gate_shared_free(struct clk *clk)
 {
-	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+	struct clk_hw *hw = clk_to_clk_hw(clk);
+	struct clk_gate_shared *g = to_clk_gate_shared(hw);
 
 	free(g);
 }
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 6a6fd66e4e..6e1bf0b316 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -10,9 +10,9 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-static void clk_gate_endisable(struct clk *clk, int enable)
+static void clk_gate_endisable(struct clk_hw *hw, int enable)
 {
-	struct clk_gate *gate = container_of(clk, struct clk_gate, clk);
+	struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
 	int set = gate->flags & CLK_GATE_INVERTED ? 1 : 0;
 	u32 val;
 
@@ -34,21 +34,21 @@ static void clk_gate_endisable(struct clk *clk, int enable)
 	writel(val, gate->reg);
 }
 
-static int clk_gate_enable(struct clk *clk)
+static int clk_gate_enable(struct clk_hw *hw)
 {
-	clk_gate_endisable(clk, 1);
+	clk_gate_endisable(hw, 1);
 
 	return 0;
 }
 
-static void clk_gate_disable(struct clk *clk)
+static void clk_gate_disable(struct clk_hw *hw)
 {
-	clk_gate_endisable(clk, 0);
+	clk_gate_endisable(hw, 0);
 }
 
-int clk_gate_is_enabled(struct clk *clk)
+int clk_gate_is_enabled(struct clk_hw *hw)
 {
-	struct clk_gate *g = container_of(clk, struct clk_gate, clk);
+	struct clk_gate *g = container_of(hw, struct clk_gate, hw);
 	u32 val;
 
 	val = readl(g->reg);
@@ -75,19 +75,20 @@ struct clk *clk_gate_alloc(const char *name, const char *parent,
 	g->parent = parent;
 	g->reg = reg;
 	g->shift = shift;
-	g->clk.ops = &clk_gate_ops;
-	g->clk.name = name;
-	g->clk.flags = flags;
-	g->clk.parent_names = &g->parent;
-	g->clk.num_parents = 1;
+	g->hw.clk.ops = &clk_gate_ops;
+	g->hw.clk.name = name;
+	g->hw.clk.flags = flags;
+	g->hw.clk.parent_names = &g->parent;
+	g->hw.clk.num_parents = 1;
 	g->flags = clk_gate_flags;
 
-	return &g->clk;
+	return &g->hw.clk;
 }
 
 void clk_gate_free(struct clk *clk_gate)
 {
-	struct clk_gate *g = to_clk_gate(clk_gate);
+	struct clk_hw *hw = clk_to_clk_hw(clk_gate);
+	struct clk_gate *g = to_clk_gate(hw);
 
 	free(g);
 }
@@ -102,7 +103,8 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
 
 	ret = bclk_register(g);
 	if (ret) {
-		free(to_clk_gate(g));
+		struct clk_hw *hw = clk_to_clk_hw(g);
+		free(to_clk_gate(hw));
 		return ERR_PTR(ret);
 	}
 
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index e47474a5cc..6ac2e820fa 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -14,30 +14,30 @@
 #include <init.h>
 
 struct clk_gpio {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	int gpio;
 };
-#define to_clk_gpio(_clk) container_of(_clk, struct clk_gpio, clk)
+#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
 
-static int clk_gpio_enable(struct clk *clk)
+static int clk_gpio_enable(struct clk_hw *hw)
 {
-	struct clk_gpio *clk_gpio = to_clk_gpio(clk);
+	struct clk_gpio *clk_gpio = to_clk_gpio(hw);
 
 	gpio_set_active(clk_gpio->gpio, true);
 	return 0;
 }
 
-static void clk_gpio_disable(struct clk *clk)
+static void clk_gpio_disable(struct clk_hw *hw)
 {
-	struct clk_gpio *clk_gpio = to_clk_gpio(clk);
+	struct clk_gpio *clk_gpio = to_clk_gpio(hw);
 
 	gpio_set_active(clk_gpio->gpio, false);
 }
 
-static int clk_gpio_is_enabled(struct clk *clk)
+static int clk_gpio_is_enabled(struct clk_hw *hw)
 {
-	struct clk_gpio *clk_gpio = to_clk_gpio(clk);
+	struct clk_gpio *clk_gpio = to_clk_gpio(hw);
 
 	return gpio_is_active(clk_gpio->gpio);
 }
@@ -67,13 +67,13 @@ static int of_gpio_clk_setup(struct device_node *node)
 		goto no_parent;
 	}
 
-	clk_gpio->clk.ops = &clk_gpio_ops;
-	clk_gpio->clk.parent_names = &clk_gpio->parent;
-	clk_gpio->clk.num_parents = 1;
+	clk_gpio->hw.clk.ops = &clk_gpio_ops;
+	clk_gpio->hw.clk.parent_names = &clk_gpio->parent;
+	clk_gpio->hw.clk.num_parents = 1;
 
-	clk_gpio->clk.name = node->name;
+	clk_gpio->hw.clk.name = node->name;
 	of_property_read_string(node, "clock-output-names",
-			&clk_gpio->clk.name);
+			&clk_gpio->hw.clk.name);
 
 	ret = of_get_named_gpio_flags(node, "enable-gpios", 0,
 			&of_flags);
@@ -86,15 +86,15 @@ static int of_gpio_clk_setup(struct device_node *node)
 	flags = GPIOF_OUT_INIT_ACTIVE;
 	if (of_flags & OF_GPIO_ACTIVE_LOW)
 		flags |= GPIOF_ACTIVE_LOW;
-	ret = gpio_request_one(clk_gpio->gpio, flags, clk_gpio->clk.name);
+	ret = gpio_request_one(clk_gpio->gpio, flags, clk_gpio->hw.clk.name);
 	if (ret)
 		goto no_request;
 
-	ret = bclk_register(&clk_gpio->clk);
+	ret = bclk_register(&clk_gpio->hw.clk);
 	if (ret)
 		goto no_register;
 
-	return of_clk_add_provider(node, of_clk_src_simple_get, &clk_gpio->clk);
+	return of_clk_add_provider(node, of_clk_src_simple_get, &clk_gpio->hw.clk);
 
 no_register:
 	gpio_free(clk_gpio->gpio);
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index b5618cefd3..981f3aa853 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -10,21 +10,21 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-static int clk_mux_get_parent(struct clk *clk)
+static int clk_mux_get_parent(struct clk_hw *hw)
 {
-	struct clk_mux *m = container_of(clk, struct clk_mux, clk);
+	struct clk_mux *m = to_clk_mux(hw);
 	int idx = readl(m->reg) >> m->shift & ((1 << m->width) - 1);
 
 	return idx;
 }
 
-static int clk_mux_set_parent(struct clk *clk, u8 idx)
+static int clk_mux_set_parent(struct clk_hw *hw, u8 idx)
 {
-	struct clk_mux *m = container_of(clk, struct clk_mux, clk);
+	struct clk_mux *m = to_clk_mux(hw);
 	u32 val;
 
 	if (m->flags & CLK_MUX_READ_ONLY) {
-		if (clk_mux_get_parent(clk) != idx)
+		if (clk_mux_get_parent(hw) != idx)
 			return -EPERM;
 		else
 			return 0;
@@ -58,18 +58,19 @@ struct clk *clk_mux_alloc(const char *name, unsigned clk_flags, void __iomem *re
 	m->shift = shift;
 	m->width = width;
 	m->flags = mux_flags;
-	m->clk.ops = &clk_mux_ops;
-	m->clk.name = name;
-	m->clk.flags = clk_flags;
-	m->clk.parent_names = parents;
-	m->clk.num_parents = num_parents;
+	m->hw.clk.ops = &clk_mux_ops;
+	m->hw.clk.name = name;
+	m->hw.clk.flags = clk_flags;
+	m->hw.clk.parent_names = parents;
+	m->hw.clk.num_parents = num_parents;
 
-	return &m->clk;
+	return &m->hw.clk;
 }
 
 void clk_mux_free(struct clk *clk_mux)
 {
-	struct clk_mux *m = to_clk_mux(clk_mux);
+	struct clk_hw *hw = clk_to_clk_hw(clk_mux);
+	struct clk_mux *m = to_clk_mux(hw);
 
 	free(m);
 }
@@ -86,7 +87,8 @@ struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
 
 	ret = bclk_register(m);
 	if (ret) {
-		free(to_clk_mux(m));
+		struct clk_hw *hw = clk_to_clk_hw(m);
+		free(to_clk_mux(hw));
 		return ERR_PTR(ret);
 	}
 
diff --git a/drivers/clk/clk-qoric.c b/drivers/clk/clk-qoric.c
index 328570400f..f7dbf7230d 100644
--- a/drivers/clk/clk-qoric.c
+++ b/drivers/clk/clk-qoric.c
@@ -29,7 +29,7 @@
 #define CGB_PLL2	5
 
 struct clockgen_pll_div {
-	struct clk *clk;
+	struct clk_hw *hw;
 	char name[32];
 };
 
@@ -254,20 +254,20 @@ static const struct clockgen_chipinfo chipinfo_ls2080a = {
 };
 
 struct mux_hwclock {
-	struct clk clk;
+	struct clk_hw hw;
 	struct clockgen *cg;
 	const struct clockgen_muxinfo *info;
 	u32 __iomem *reg;
 	int num_parents;
 };
 
-#define to_mux_hwclock(p)	container_of(p, struct mux_hwclock, clk)
+#define to_mux_hwclock(p)	container_of(p, struct mux_hwclock, hw)
 #define CLKSEL_MASK		0x78000000
 #define	CLKSEL_SHIFT		27
 
-static int mux_set_parent(struct clk *clk, u8 idx)
+static int mux_set_parent(struct clk_hw *hw, u8 idx)
 {
-	struct mux_hwclock *hwc = to_mux_hwclock(clk);
+	struct mux_hwclock *hwc = to_mux_hwclock(hw);
 
 	if (idx >= hwc->num_parents)
 		return -EINVAL;
@@ -277,9 +277,9 @@ static int mux_set_parent(struct clk *clk, u8 idx)
 	return 0;
 }
 
-static int mux_get_parent(struct clk *clk)
+static int mux_get_parent(struct clk_hw *hw)
 {
-	struct mux_hwclock *hwc = to_mux_hwclock(clk);
+	struct mux_hwclock *hwc = to_mux_hwclock(hw);
 
 	return (cg_in(hwc->cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
 }
@@ -318,7 +318,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
 					     const struct clk_ops *ops,
 					     const char *fmt, int idx)
 {
-	struct clk *clk = &hwc->clk;
+	struct clk_hw *hw = &hwc->hw;
 	const struct clockgen_pll_div *div;
 	const char **parent_names;
 	int i, ret;
@@ -333,20 +333,20 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
 		parent_names[i] = div->name;
 	}
 
-	clk->name = xasprintf(fmt, idx);;
-	clk->ops = ops;
-	clk->parent_names = parent_names;
-	clk->num_parents = hwc->num_parents = i;
+	hw->clk.name = xasprintf(fmt, idx);;
+	hw->clk.ops = ops;
+	hw->clk.parent_names = parent_names;
+	hw->clk.num_parents = hwc->num_parents = i;
 	hwc->cg = cg;
 
-	ret = bclk_register(clk);
+	ret = bclk_register(&hw->clk);
 	if (ret) {
-		pr_err("%s: Couldn't register %s: %d\n", __func__, clk->name, ret);
+		pr_err("%s: Couldn't register %s: %d\n", __func__, clk_hw_get_name(hw), ret);
 		kfree(hwc);
 		return NULL;
 	}
 
-	return clk;
+	return &hw->clk;
 }
 
 static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
@@ -499,7 +499,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
 			continue;
 		}
 
-		pll->div[i].clk = clk;
+		pll->div[i].hw = clk_to_clk_hw(clk);
 	}
 }
 
@@ -551,7 +551,7 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
 		pll = &cg->pll[PLATFORM_PLL];
 		if (idx >= ARRAY_SIZE(pll->div))
 			goto bad_args;
-		clk = pll->div[idx].clk;
+		clk = clk_hw_to_clk(pll->div[idx].hw);
 		break;
 	case 5:
 		if (idx != 0)
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 2996877577..7ba71b4592 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -285,7 +285,7 @@ static const struct clk_div_table ck_trace_div_table[] = {
 
 struct stm32_mmux {
 	u8 nbr_clk;
-	struct clk *hws[MAX_MUX_CLK];
+	struct clk_hw *hws[MAX_MUX_CLK];
 };
 
 struct stm32_clk_mmux {
@@ -419,19 +419,19 @@ _clk_hw_register_mux(void __iomem *base,
 
 /* MP1 Gate clock with set & clear registers */
 
-static int mp1_gate_clk_enable(struct clk *clk)
+static int mp1_gate_clk_enable(struct clk_hw *hw)
 {
-	if (!clk_gate_ops.is_enabled(clk))
-		clk_gate_ops.enable(clk);
+	if (!clk_gate_ops.is_enabled(hw))
+		clk_gate_ops.enable(hw);
 
 	return 0;
 }
 
-static void mp1_gate_clk_disable(struct clk *clk)
+static void mp1_gate_clk_disable(struct clk_hw *hw)
 {
-	struct clk_gate *gate = to_clk_gate(clk);
+	struct clk_gate *gate = to_clk_gate(hw);
 
-	if (clk_gate_ops.is_enabled(clk)) {
+	if (clk_gate_ops.is_enabled(hw)) {
 		writel(BIT(gate->shift), gate->reg + RCC_CLR);
 	}
 }
@@ -442,12 +442,12 @@ static const struct clk_ops mp1_gate_clk_ops = {
 	.is_enabled	= clk_gate_is_enabled,
 };
 
-static struct clk *_get_stm32_mux(void __iomem *base,
+static struct clk_hw *_get_stm32_mux(void __iomem *base,
 				     const struct stm32_mux_cfg *cfg)
 {
 	struct stm32_clk_mmux *mmux;
 	struct clk_mux *mux;
-	struct clk *mux_hw;
+	struct clk_hw *mux_hw;
 
 	if (cfg->mmux) {
 		mmux = kzalloc(sizeof(*mmux), GFP_KERNEL);
@@ -458,7 +458,7 @@ static struct clk *_get_stm32_mux(void __iomem *base,
 		mmux->mux.shift = cfg->mux->shift;
 		mmux->mux.width = cfg->mux->width;
 		mmux->mmux = cfg->mmux;
-		mux_hw = &mmux->mux.clk;
+		mux_hw = &mmux->mux.hw;
 		cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw;
 		mux = &mmux->mux;
 	} else {
@@ -469,18 +469,18 @@ static struct clk *_get_stm32_mux(void __iomem *base,
 		mux->reg = cfg->mux->reg_off + base;
 		mux->shift = cfg->mux->shift;
 		mux->width = cfg->mux->width;
-		mux_hw = &mux->clk;
+		mux_hw = &mux->hw;
 	}
 
 	if (cfg->ops)
-		mux->clk.ops = cfg->ops;
+		mux->hw.clk.ops = cfg->ops;
 	else
-		mux->clk.ops = &clk_mux_ops;
+		mux->hw.clk.ops = &clk_mux_ops;
 
 	return mux_hw;
 }
 
-static struct clk *_get_stm32_div(void __iomem *base,
+static struct clk_hw *_get_stm32_div(void __iomem *base,
 				     const struct stm32_div_cfg *cfg)
 {
 	struct clk_divider *div;
@@ -496,11 +496,11 @@ static struct clk *_get_stm32_div(void __iomem *base,
 	div->table = cfg->div->table;
 
 	if (cfg->ops)
-		div->clk.ops = cfg->ops;
+		div->hw.clk.ops = cfg->ops;
 	else
-		div->clk.ops = &clk_divider_ops;
+		div->hw.clk.ops = &clk_divider_ops;
 
-	return &div->clk;
+	return &div->hw;
 }
 
 static struct clk_gate *
@@ -535,9 +535,9 @@ _get_stm32_gate(void __iomem *base,
 	}
 	
 	if (cfg->ops)
-		gate->clk.ops = cfg->ops;
+		gate->hw.clk.ops = cfg->ops;
 	else
-		gate->clk.ops = &clk_gate_ops;
+		gate->hw.clk.ops = &clk_gate_ops;
 
 	return gate;
 }
@@ -558,7 +558,7 @@ clk_stm32_register_gate_ops(const char *name,
 		return ERR_PTR(-ENOMEM);
 
 	gate->parent = parent_name;
-	clk = &gate->clk;
+	clk = &gate->hw.clk;
 	clk->name = name;
 	clk->parent_names = &gate->parent;
 	clk->num_parents = 1;
@@ -577,7 +577,7 @@ clk_stm32_register_composite(const char *name, const char * const *parent_names,
 			     const struct stm32_composite_cfg *cfg,
 			     unsigned long flags)
 {
-	struct clk *mux_hw, *div_hw, *gate_hw;
+	struct clk_hw *mux_hw, *div_hw, *gate_hw;
 	struct clk_gate *gate;
 
 	mux_hw = NULL;
@@ -592,36 +592,36 @@ clk_stm32_register_composite(const char *name, const char * const *parent_names,
 
 	if (cfg->gate) {
 		gate = _get_stm32_gate(base, cfg->gate);
-		gate_hw = &gate->clk;
+		gate_hw = &gate->hw;
 	}
 
 	return clk_register_composite(name, parent_names, num_parents,
-				       mux_hw, div_hw, gate_hw, flags);
+				       &mux_hw->clk, &div_hw->clk, &gate_hw->clk, flags);
 }
 
 #define to_clk_mgate(_gate) container_of(_gate, struct stm32_clk_mgate, gate)
 
-static int mp1_mgate_clk_enable(struct clk *clk)
+static int mp1_mgate_clk_enable(struct clk_hw *hw)
 {
-	struct clk_gate *gate = to_clk_gate(clk);
+	struct clk_gate *gate = to_clk_gate(hw);
 	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
 
 	clk_mgate->mgate->flag |= clk_mgate->mask;
 
-	mp1_gate_clk_enable(clk);
+	mp1_gate_clk_enable(hw);
 
 	return  0;
 }
 
-static void mp1_mgate_clk_disable(struct clk *clk)
+static void mp1_mgate_clk_disable(struct clk_hw *hw)
 {
-	struct clk_gate *gate = to_clk_gate(clk);
+	struct clk_gate *gate = to_clk_gate(hw);
 	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
 
 	clk_mgate->mgate->flag &= ~clk_mgate->mask;
 
 	if (clk_mgate->mgate->flag == 0)
-		mp1_gate_clk_disable(clk);
+		mp1_gate_clk_disable(hw);
 }
 
 static const struct clk_ops mp1_mgate_clk_ops = {
@@ -633,26 +633,26 @@ static const struct clk_ops mp1_mgate_clk_ops = {
 
 #define to_clk_mmux(_mux) container_of(_mux, struct stm32_clk_mmux, mux)
 
-static int clk_mmux_get_parent(struct clk *clk)
+static int clk_mmux_get_parent(struct clk_hw *hw)
 {
-	return clk_mux_ops.get_parent(clk);
+	return clk_mux_ops.get_parent(hw);
 }
 
-static int clk_mmux_set_parent(struct clk *clk, u8 index)
+static int clk_mmux_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_mux *mux = to_clk_mux(clk);
+	struct clk_mux *mux = to_clk_mux(hw);
 	struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux);
-	struct clk *parent;
+	struct clk_hw *hwp;
 	int ret, n;
 
-	ret = clk_mux_ops.set_parent(clk, index);
+	ret = clk_mux_ops.set_parent(hw, index);
 	if (ret)
 		return ret;
 
-	parent = clk_get_parent(clk);
+	hwp = clk_hw_get_parent(hw);
 
 	for (n = 0; n < clk_mmux->mmux->nbr_clk; n++)
-		clk_set_parent(clk_mmux->mmux->hws[n], parent);
+		clk_hw_set_parent(clk_mmux->mmux->hws[n], hw);
 
 	return 0;
 }
@@ -691,8 +691,9 @@ static int __pll_is_enabled(struct clk *clk)
 
 #define TIMEOUT 5
 
-static int pll_enable(struct clk *clk)
+static int pll_enable(struct clk_hw *hw)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct stm32_pll_obj *clk_elem = to_pll(clk);
 	u32 reg;
 	unsigned int timeout = TIMEOUT;
@@ -722,8 +723,9 @@ unlock:
 	return bit_status;
 }
 
-static void pll_disable(struct clk *clk)
+static void pll_disable(struct clk_hw *hw)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct stm32_pll_obj *clk_elem = to_pll(clk);
 	u32 reg;
 
@@ -744,9 +746,10 @@ static u32 pll_frac_val(struct clk *clk)
 	return frac;
 }
 
-static unsigned long pll_recalc_rate(struct clk *clk,
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
 				     unsigned long parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct stm32_pll_obj *clk_elem = to_pll(clk);
 	u32 reg;
 	u32 frac, divm, divn;
@@ -769,8 +772,9 @@ static unsigned long pll_recalc_rate(struct clk *clk,
 	return rate + rate_frac;
 }
 
-static int pll_is_enabled(struct clk *clk)
+static int pll_is_enabled(struct clk_hw *hw)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	int ret;
 
 	ret = __pll_is_enabled(clk);
@@ -852,17 +856,19 @@ static unsigned long __bestmult(struct clk *clk, unsigned long rate,
 	return mult;
 }
 
-static long timer_ker_round_rate(struct clk *clk, unsigned long rate,
+static long timer_ker_round_rate(struct clk_hw *hw, unsigned long rate,
 				 unsigned long *parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	unsigned long factor = __bestmult(clk, rate, *parent_rate);
 
 	return *parent_rate * factor;
 }
 
-static int timer_ker_set_rate(struct clk *clk, unsigned long rate,
+static int timer_ker_set_rate(struct clk_hw *hw, unsigned long rate,
 			      unsigned long parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct timer_cker *tim_ker = to_timer_cker(clk);
 	unsigned long factor = __bestmult(clk, rate, parent_rate);
 	int ret = 0;
@@ -883,10 +889,11 @@ static int timer_ker_set_rate(struct clk *clk, unsigned long rate,
 	return ret;
 }
 
-static unsigned long timer_ker_recalc_rate(struct clk *hw,
+static unsigned long timer_ker_recalc_rate(struct clk_hw *hw,
 					   unsigned long parent_rate)
 {
-	struct timer_cker *tim_ker = to_timer_cker(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct timer_cker *tim_ker = to_timer_cker(clk);
 	u32 prescaler, timpre;
 	u32 mul;
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7dab6a5fb9..73682126bf 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -36,6 +36,7 @@ static void clk_parent_disable(struct clk *clk)
 
 int clk_enable(struct clk *clk)
 {
+	struct clk_hw *hw;
 	int ret;
 
 	if (!clk)
@@ -44,13 +45,15 @@ int clk_enable(struct clk *clk)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	hw = clk_to_clk_hw(clk);
+
 	if (!clk->enable_count) {
 		ret = clk_parent_enable(clk);
 		if (ret)
 			return ret;
 
 		if (clk->ops->enable) {
-			ret = clk->ops->enable(clk);
+			ret = clk->ops->enable(hw);
 			if (ret) {
 				clk_parent_disable(clk);
 				return ret;
@@ -65,6 +68,8 @@ int clk_enable(struct clk *clk)
 
 void clk_disable(struct clk *clk)
 {
+	struct clk_hw *hw;
+
 	if (!clk)
 		return;
 
@@ -81,9 +86,11 @@ void clk_disable(struct clk *clk)
 
 	clk->enable_count--;
 
+	hw = clk_to_clk_hw(clk);
+
 	if (!clk->enable_count) {
 		if (clk->ops->disable)
-			clk->ops->disable(clk);
+			clk->ops->disable(hw);
 
 		clk_parent_disable(clk);
 	}
@@ -91,6 +98,7 @@ void clk_disable(struct clk *clk)
 
 unsigned long clk_get_rate(struct clk *clk)
 {
+	struct clk_hw *hw;
 	struct clk *parent;
 	unsigned long parent_rate = 0;
 
@@ -106,14 +114,22 @@ unsigned long clk_get_rate(struct clk *clk)
 	if (!IS_ERR_OR_NULL(parent))
 		parent_rate = clk_get_rate(parent);
 
+	hw = clk_to_clk_hw(clk);
+
 	if (clk->ops->recalc_rate)
-		return clk->ops->recalc_rate(clk, parent_rate);
+		return clk->ops->recalc_rate(hw, parent_rate);
 
 	return parent_rate;
 }
 
+unsigned long clk_hw_get_rate(struct clk_hw *hw)
+{
+	return clk_get_rate(clk_hw_to_clk(hw));
+}
+
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
+	struct clk_hw *hw;
 	unsigned long parent_rate = 0;
 	struct clk *parent;
 
@@ -127,14 +143,22 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 	if (parent)
 		parent_rate = clk_get_rate(parent);
 
+	hw = clk_to_clk_hw(clk);
+
 	if (clk->ops->round_rate)
-		return clk->ops->round_rate(clk, rate, &parent_rate);
+		return clk->ops->round_rate(hw, rate, &parent_rate);
 
 	return clk_get_rate(clk);
 }
 
+long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
+{
+	return clk_round_rate(&hw->clk, rate);
+}
+
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
+	struct clk_hw *hw;
 	struct clk *parent;
 	unsigned long parent_rate = 0;
 	int ret;
@@ -159,7 +183,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 		}
 	}
 
-	ret = clk->ops->set_rate(clk, rate, parent_rate);
+	hw = clk_to_clk_hw(clk);
+
+	ret = clk->ops->set_rate(hw, rate, parent_rate);
 
 	if (parent && clk->flags & CLK_OPS_PARENT_ENABLE)
 		clk_disable(parent);
@@ -167,6 +193,11 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	return ret;
 }
 
+int clk_hw_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+	return clk_set_rate(&hw->clk, rate);
+}
+
 struct clk *clk_lookup(const char *name)
 {
 	struct clk *c;
@@ -184,6 +215,7 @@ struct clk *clk_lookup(const char *name)
 
 int clk_set_parent(struct clk *clk, struct clk *newparent)
 {
+	struct clk_hw *hw;
 	int i, ret;
 	struct clk *curparent = clk_get_parent(clk);
 
@@ -217,7 +249,9 @@ int clk_set_parent(struct clk *clk, struct clk *newparent)
 		clk_enable(newparent);
 	}
 
-	ret = clk->ops->set_parent(clk, i);
+	hw = clk_to_clk_hw(clk);
+
+	ret = clk->ops->set_parent(hw, i);
 
 	if (clk->flags & CLK_OPS_PARENT_ENABLE) {
 		clk_disable(curparent);
@@ -230,8 +264,14 @@ int clk_set_parent(struct clk *clk, struct clk *newparent)
 	return ret;
 }
 
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *newparent)
+{
+	return clk_set_parent(&hw->clk, &newparent->clk);
+}
+
 struct clk *clk_get_parent(struct clk *clk)
 {
+	struct clk_hw *hw;
 	int idx;
 
 	if (IS_ERR(clk))
@@ -240,11 +280,13 @@ struct clk *clk_get_parent(struct clk *clk)
 	if (!clk->num_parents)
 		return ERR_PTR(-ENODEV);
 
+	hw = clk_to_clk_hw(clk);
+
 	if (clk->num_parents != 1) {
 		if (!clk->ops->get_parent)
 			return ERR_PTR(-EINVAL);
 
-		idx = clk->ops->get_parent(clk);
+		idx = clk->ops->get_parent(hw);
 
 		if (idx >= clk->num_parents)
 			return ERR_PTR(-ENODEV);
@@ -258,8 +300,19 @@ struct clk *clk_get_parent(struct clk *clk)
 	return clk->parents[idx];
 }
 
+struct clk_hw *clk_hw_get_parent(struct clk_hw *hw)
+{
+	struct clk *clk = clk_get_parent(clk_hw_to_clk(hw));
+
+	if (IS_ERR(clk))
+		return ERR_CAST(clk);
+
+	return clk_to_clk_hw(clk);
+}
+
 int bclk_register(struct clk *clk)
 {
+	struct clk_hw *hw = clk_to_clk_hw(clk);
 	struct clk *c;
 	int ret;
 
@@ -276,7 +329,7 @@ int bclk_register(struct clk *clk)
 	list_add_tail(&clk->list, &clks);
 
 	if (clk->ops->init) {
-		ret = clk->ops->init(clk);
+		ret = clk->ops->init(hw);
 		if (ret)
 			goto out;
 	}
@@ -295,6 +348,7 @@ out:
 int clk_is_enabled(struct clk *clk)
 {
 	int enabled;
+	struct clk_hw *hw = clk_to_clk_hw(clk);
 
 	if (IS_ERR(clk))
 		return 0;
@@ -303,7 +357,7 @@ int clk_is_enabled(struct clk *clk)
 		/*
 		 * If we can ask a clk, do it
 		 */
-		enabled = clk->ops->is_enabled(clk);
+		enabled = clk->ops->is_enabled(hw);
 	} else {
 		if (clk->ops->enable) {
 			/*
@@ -332,26 +386,35 @@ int clk_is_enabled(struct clk *clk)
 	return clk_is_enabled(clk);
 }
 
+int clk_hw_is_enabled(struct clk_hw *hw)
+{
+	return clk_is_enabled(&hw->clk);
+}
+
 /*
  * Generic struct clk_ops callbacks
  */
-int clk_is_enabled_always(struct clk *clk)
+int clk_is_enabled_always(struct clk_hw *hw)
 {
 	return 1;
 }
 
-long clk_parent_round_rate(struct clk *clk, unsigned long rate,
+long clk_parent_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
+
 	if (!(clk->flags & CLK_SET_RATE_PARENT))
 		return *prate;
 
 	return clk_round_rate(clk_get_parent(clk), rate);
 }
 
-int clk_parent_set_rate(struct clk *clk, unsigned long rate,
+int clk_parent_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
+
 	if (!(clk->flags & CLK_SET_RATE_PARENT))
 		return 0;
 	return clk_set_rate(clk_get_parent(clk), rate);
@@ -675,8 +738,10 @@ int of_clk_init(struct device_node *root, const struct of_device_id *matches)
 
 static const char *clk_hw_stat(struct clk *clk)
 {
+	struct clk_hw *hw = clk_to_clk_hw(clk);
+
 	if (clk->ops->is_enabled) {
-		if (clk->ops->is_enabled(clk))
+		if (clk->ops->is_enabled(hw))
 			return "enabled";
 		else
 			return "disabled";
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 6c7f10a2c9..96fccc51d8 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -26,10 +26,11 @@
 
 #define clk_div_mask(width)	((1 << (width)) - 1)
 
-static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk *clk,
+static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw,
 						unsigned long parent_rate)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
+	struct clk *clk = clk_hw_to_clk(hw);
 	unsigned long prediv_rate;
 	unsigned int prediv_value;
 	unsigned int div_value;
@@ -74,7 +75,7 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate,
 	return ret;
 }
 
-static long imx8m_clk_composite_divider_round_rate(struct clk *clk,
+static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw,
 						unsigned long rate,
 						unsigned long *prate)
 {
@@ -89,11 +90,11 @@ static long imx8m_clk_composite_divider_round_rate(struct clk *clk,
 
 }
 
-static int imx8m_clk_composite_divider_set_rate(struct clk *clk,
+static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw,
 					unsigned long rate,
 					unsigned long parent_rate)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
 	int prediv_value;
 	int div_value;
 	int ret;
@@ -114,14 +115,14 @@ static int imx8m_clk_composite_divider_set_rate(struct clk *clk,
 
 	return ret;
 }
-static int imx8m_clk_composite_mux_get_parent(struct clk *clk)
+static int imx8m_clk_composite_mux_get_parent(struct clk_hw *hw)
 {
-	return clk_mux_ops.get_parent(clk);
+	return clk_mux_ops.get_parent(hw);
 }
 
-static int imx8m_clk_composite_mux_set_parent(struct clk *clk, u8 index)
+static int imx8m_clk_composite_mux_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct clk_mux *m = container_of(clk, struct clk_mux, clk);
+	struct clk_mux *m = container_of(hw, struct clk_mux, hw);
 	u32 val;
 
 	val = readl(m->reg);
@@ -161,7 +162,6 @@ struct clk *imx8m_clk_composite_flags(const char *name,
 	struct clk_divider *div = NULL;
 	struct clk_gate *gate = NULL;
 	struct clk_mux *mux = NULL;
-	const struct clk_ops *divider_ops;
 	const struct clk_ops *mux_ops;
 
 	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
@@ -171,7 +171,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
 	mux->reg = reg;
 	mux->shift = PCG_PCS_SHIFT;
 	mux->width = PCG_PCS_WIDTH;
-	mux->clk.ops = &clk_mux_ops;
+	mux->hw.clk.ops = &clk_mux_ops;
 
 	div = kzalloc(sizeof(*div), GFP_KERNEL);
 	if (!div)
@@ -181,20 +181,19 @@ struct clk *imx8m_clk_composite_flags(const char *name,
 	if (composite_flags & IMX_COMPOSITE_CORE) {
 		div->shift = PCG_DIV_SHIFT;
 		div->width = PCG_CORE_DIV_WIDTH;
-		divider_ops = &clk_divider_ops;
+		div->hw.clk.ops = &clk_divider_ops;
 		mux_ops = &imx8m_clk_composite_mux_ops;
 	} else if (composite_flags & IMX_COMPOSITE_BUS) {
 		div->shift = PCG_PREDIV_SHIFT;
 		div->width = PCG_PREDIV_WIDTH;
-		divider_ops = &imx8m_clk_composite_divider_ops;
+		div->hw.clk.ops = &imx8m_clk_composite_divider_ops;
 		mux_ops = &imx8m_clk_composite_mux_ops;
 	} else {
 		div->shift = PCG_PREDIV_SHIFT;
 		div->width = PCG_PREDIV_WIDTH;
-		divider_ops = &imx8m_clk_composite_divider_ops;
+		div->hw.clk.ops = &imx8m_clk_composite_divider_ops;
 		mux_ops = &clk_mux_ops;
 	}
-	div->clk.ops = divider_ops;
 
 	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 	if (!gate)
@@ -202,10 +201,10 @@ struct clk *imx8m_clk_composite_flags(const char *name,
 
 	gate->reg = reg;
 	gate->shift = PCG_CGC_SHIFT;
-	gate->clk.ops = &clk_gate_ops;
+	gate->hw.clk.ops = &clk_gate_ops;
 
 	comp = clk_register_composite(name, parent_names, num_parents,
-				      &mux->clk, &div->clk, &gate->clk, flags);
+				      &mux->hw.clk, &div->hw.clk, &gate->hw.clk, flags);
 	if (IS_ERR(comp))
 		goto fail;
 
diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c
index 8ed899cb98..0ca5dd63c5 100644
--- a/drivers/clk/imx/clk-cpu.c
+++ b/drivers/clk/imx/clk-cpu.c
@@ -16,38 +16,38 @@
 #include "clk.h"
 
 struct clk_cpu {
-	struct clk	clk;
+	struct clk_hw	hw;
 	struct clk	*div;
 	struct clk	*mux;
 	struct clk	*pll;
 	struct clk	*step;
 };
 
-static inline struct clk_cpu *to_clk_cpu(struct clk *clk)
+static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw)
 {
-	return container_of(clk, struct clk_cpu, clk);
+	return container_of(hw, struct clk_cpu, hw);
 }
 
-static unsigned long clk_cpu_recalc_rate(struct clk *clk,
+static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_cpu *cpu = to_clk_cpu(clk);
+	struct clk_cpu *cpu = to_clk_cpu(hw);
 
 	return clk_get_rate(cpu->div);
 }
 
-static long clk_cpu_round_rate(struct clk *clk, unsigned long rate,
+static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
-	struct clk_cpu *cpu = to_clk_cpu(clk);
+	struct clk_cpu *cpu = to_clk_cpu(hw);
 
 	return clk_round_rate(cpu->pll, rate);
 }
 
-static int clk_cpu_set_rate(struct clk *clk, unsigned long rate,
+static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_cpu *cpu = to_clk_cpu(clk);
+	struct clk_cpu *cpu = to_clk_cpu(hw);
 	int ret;
 
 	/* switch to PLL bypass clock */
@@ -98,17 +98,17 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
 	cpu->pll = pll;
 	cpu->step = step;
 
-	cpu->clk.name = name;
-	cpu->clk.ops = &clk_cpu_ops;
-	cpu->clk.flags = CLK_IS_CRITICAL;
-	cpu->clk.parent_names = &icpu->parent_name;
-	cpu->clk.num_parents = 1;
+	cpu->hw.clk.name = name;
+	cpu->hw.clk.ops = &clk_cpu_ops;
+	cpu->hw.clk.flags = CLK_IS_CRITICAL;
+	cpu->hw.clk.parent_names = &icpu->parent_name;
+	cpu->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&cpu->clk);
+	ret = bclk_register(&cpu->hw.clk);
 	if (ret) {
 		free(cpu);
 		return NULL;
 	}
 
-	return &cpu->clk;
+	return &cpu->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c
index bc62505e57..d3fc760717 100644
--- a/drivers/clk/imx/clk-frac-pll.c
+++ b/drivers/clk/imx/clk-frac-pll.c
@@ -26,12 +26,12 @@
 #define PLL_FRAC_DENOM		0x1000000
 
 struct clk_frac_pll {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*base;
 	const char *parent;
 };
 
-#define to_clk_frac_pll(_clk) container_of(_clk, struct clk_frac_pll, clk)
+#define to_clk_frac_pll(_hw) container_of(_hw, struct clk_frac_pll, hw)
 
 static int clk_wait_lock(struct clk_frac_pll *pll)
 {
@@ -63,9 +63,9 @@ static int clk_wait_ack(struct clk_frac_pll *pll)
 	return readl(pll->base) & PLL_NEWDIV_ACK ? 0 : ETIMEDOUT;
 }
 
-static int clk_pll_enable(struct clk *clk)
+static int clk_pll_enable(struct clk_hw *hw)
 {
-	struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+	struct clk_frac_pll *pll = to_clk_frac_pll(hw);
 	u32 val;
 
 	val = readl(pll->base + PLL_CFG0);
@@ -75,9 +75,9 @@ static int clk_pll_enable(struct clk *clk)
 	return clk_wait_lock(pll);
 }
 
-static void clk_pll_disable(struct clk *clk)
+static void clk_pll_disable(struct clk_hw *hw)
 {
-	struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+	struct clk_frac_pll *pll = to_clk_frac_pll(hw);
 	u32 val;
 
 	val = readl(pll->base + PLL_CFG0);
@@ -85,19 +85,19 @@ static void clk_pll_disable(struct clk *clk)
 	writel(val, pll->base + PLL_CFG0);
 }
 
-static int clk_pll_is_enabled(struct clk *clk)
+static int clk_pll_is_enabled(struct clk_hw *hw)
 {
-	struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+	struct clk_frac_pll *pll = to_clk_frac_pll(hw);
 	u32 val;
 
 	val = readl(pll->base + PLL_CFG0);
 	return (val & (1 << PLL_PD)) ? 0 : 1;
 }
 
-static unsigned long clk_pll_recalc_rate(struct clk *clk,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+	struct clk_frac_pll *pll = to_clk_frac_pll(hw);
 	u32 val, divff, divfi, divq;
 	u64 temp64;
 
@@ -115,7 +115,7 @@ static unsigned long clk_pll_recalc_rate(struct clk *clk,
 	return parent_rate * 8 * (divfi + 1) / divq + (unsigned long)temp64;
 }
 
-static long clk_pll_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
 	u32 divff, divfi;
@@ -144,10 +144,10 @@ static long clk_pll_round_rate(struct clk *clk, unsigned long rate,
  * pllout = parent_rate * 8 / 2 * DIVF_VAL;
  * where DIVF_VAL = 1 + DIVFI + DIVFF / 2^24.
  */
-static int clk_pll_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+	struct clk_frac_pll *pll = to_clk_frac_pll(hw);
 	u32 val, divfi, divff;
 	u64 temp64;
 	int ret;
@@ -205,16 +205,16 @@ struct clk *imx_clk_frac_pll(const char *name, const char *parent,
 
 	pll->base = base;
 	pll->parent = parent;
-	pll->clk.ops = &clk_frac_pll_ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.ops = &clk_frac_pll_ops;
+	pll->hw.clk.name = name;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c
index 94e7467701..473249a356 100644
--- a/drivers/clk/imx/clk-gate-exclusive.c
+++ b/drivers/clk/imx/clk-gate-exclusive.c
@@ -24,17 +24,21 @@
  * register is mutually exclusive to this gate clock.
  */
 struct clk_gate_exclusive {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	int shift;
 	const char *parent;
 	u32 exclusive_mask;
 };
 
-static int clk_gate_exclusive_enable(struct clk *clk)
+static inline struct clk_gate_exclusive *to_clk_gate_exclusive(struct clk_hw *hw)
 {
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
+	return container_of(hw, struct clk_gate_exclusive, hw);
+}
+
+static int clk_gate_exclusive_enable(struct clk_hw *hw)
+{
+	struct clk_gate_exclusive *exgate = to_clk_gate_exclusive(hw);
 	u32 val = readl(exgate->reg);
 
 	if (val & exgate->exclusive_mask)
@@ -47,10 +51,9 @@ static int clk_gate_exclusive_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_gate_exclusive_disable(struct clk *clk)
+static void clk_gate_exclusive_disable(struct clk_hw *hw)
 {
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
+	struct clk_gate_exclusive *exgate = to_clk_gate_exclusive(hw);
 	u32 val = readl(exgate->reg);
 
 	val &= ~(1 << exgate->shift);
@@ -58,10 +61,9 @@ static void clk_gate_exclusive_disable(struct clk *clk)
 	writel(val, exgate->reg);
 }
 
-static int clk_gate_exclusive_is_enabled(struct clk *clk)
+static int clk_gate_exclusive_is_enabled(struct clk_hw *hw)
 {
-	struct clk_gate_exclusive *exgate = container_of(clk,
-					struct clk_gate_exclusive, clk);
+	struct clk_gate_exclusive *exgate = to_clk_gate_exclusive(hw);
 
 	return readl(exgate->reg) & (1 << exgate->shift);
 }
@@ -80,21 +82,21 @@ struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
 
 	exgate = xzalloc(sizeof(*exgate));
 	exgate->parent = parent;
-	exgate->clk.name = name;
-	exgate->clk.ops = &clk_gate_exclusive_ops;
-	exgate->clk.flags = CLK_SET_RATE_PARENT;
-	exgate->clk.parent_names = &exgate->parent;
-	exgate->clk.num_parents = 1;
+	exgate->hw.clk.name = name;
+	exgate->hw.clk.ops = &clk_gate_exclusive_ops;
+	exgate->hw.clk.flags = CLK_SET_RATE_PARENT;
+	exgate->hw.clk.parent_names = &exgate->parent;
+	exgate->hw.clk.num_parents = 1;
 
 	exgate->reg = reg;
 	exgate->shift = shift;
 	exgate->exclusive_mask = exclusive_mask;
 
-	ret = bclk_register(&exgate->clk);
+	ret = bclk_register(&exgate->hw.clk);
 	if (ret) {
 		free(exgate);
 		return ERR_PTR(ret);
 	}
 
-	return &exgate->clk;
+ 	return &exgate->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 3d9b9338d5..8866a5365b 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -13,7 +13,7 @@
 
 
 struct clk_gate2 {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	int shift;
 	u8 cgr_val;
@@ -22,11 +22,14 @@ struct clk_gate2 {
 	unsigned flags;
 };
 
-#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+static inline struct clk_gate2 *to_clk_gate2(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_gate2, hw);
+}
 
-static int clk_gate2_enable(struct clk *clk)
+static int clk_gate2_enable(struct clk_hw *hw)
 {
-	struct clk_gate2 *g = to_clk_gate2(clk);
+	struct clk_gate2 *g = to_clk_gate2(hw);
 	u32 val;
 
 	val = readl(g->reg);
@@ -41,9 +44,9 @@ static int clk_gate2_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_gate2_disable(struct clk *clk)
+static void clk_gate2_disable(struct clk_hw *hw)
 {
-	struct clk_gate2 *g = to_clk_gate2(clk);
+	struct clk_gate2 *g = to_clk_gate2(hw);
 	u32 val;
 
 	val = readl(g->reg);
@@ -56,9 +59,9 @@ static void clk_gate2_disable(struct clk *clk)
 	writel(val, g->reg);
 }
 
-static int clk_gate2_is_enabled(struct clk *clk)
+static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
-	struct clk_gate2 *g = to_clk_gate2(clk);
+	struct clk_gate2 *g = to_clk_gate2(hw);
 	u32 val;
 
 	val = readl(g->reg);
@@ -87,13 +90,13 @@ static struct clk *clk_gate2_alloc(const char *name, const char *parent,
 	g->reg = reg;
 	g->cgr_val = cgr_val;
 	g->shift = shift;
-	g->clk.ops = &clk_gate2_ops;
-	g->clk.name = name;
-	g->clk.parent_names = &g->parent;
-	g->clk.num_parents = 1;
-	g->clk.flags = CLK_SET_RATE_PARENT | flags;
+	g->hw.clk.ops = &clk_gate2_ops;
+	g->hw.clk.name = name;
+	g->hw.clk.parent_names = &g->parent;
+	g->hw.clk.num_parents = 1;
+	g->hw.clk.flags = CLK_SET_RATE_PARENT | flags;
 
-	return &g->clk;
+	return &g->hw.clk;
 }
 
 struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
@@ -106,7 +109,8 @@ struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
 
 	ret = bclk_register(g);
 	if (ret) {
-		free(to_clk_gate2(g));
+		struct clk_hw *hw = clk_to_clk_hw(g);
+		free(to_clk_gate2(hw));
 		return ERR_PTR(ret);
 	}
 
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 6668146860..af5d582ffc 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -98,6 +98,7 @@ static int imx6_ccm_probe(struct device_d *dev)
 	void __iomem *base, *anatop_base, *ccm_base;
 	int i;
 	struct device_node *ccm_node = dev->device_node;
+	struct clk_hw *hw;
 
 	anatop_base = IOMEM(MX6_ANATOP_BASE_ADDR);
 	iores = dev_request_mem_resource(dev, 0);
@@ -445,7 +446,8 @@ static int imx6_ccm_probe(struct device_d *dev)
 				clks[IMX6UL_CLK_PLL3_PFD2]);
 
 	/* Disable GPMI_IO clk before reparenting to avoid glitches */
-	clks[IMX6UL_CLK_GPMI_IO]->ops->disable(clks[IMX6UL_CLK_GPMI_IO]);
+	hw = clk_to_clk_hw(clks[IMX6UL_CLK_GPMI_IO]);
+	clks[IMX6UL_CLK_GPMI_IO]->ops->disable(hw);
 
 	clk_set_parent(clks[IMX6UL_CLK_ENFC_SEL], clks[IMX6UL_CLK_PLL2_PFD2]);
 
diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c
index 88ede6c3fc..d16e39f85c 100644
--- a/drivers/clk/imx/clk-pfd.c
+++ b/drivers/clk/imx/clk-pfd.c
@@ -27,37 +27,37 @@
  * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
  */
 struct clk_pfd {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*reg;
 	u8		idx;
 	const char	*parent;
 };
 
-#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
+#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
 
 #define SET	0x4
 #define CLR	0x8
 #define OTG	0xc
 
-static int clk_pfd_enable(struct clk *clk)
+static int clk_pfd_enable(struct clk_hw *hw)
 {
-	struct clk_pfd *pfd = to_clk_pfd(clk);
+	struct clk_pfd *pfd = to_clk_pfd(hw);
 	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
 
 	return 0;
 }
 
-static void clk_pfd_disable(struct clk *clk)
+static void clk_pfd_disable(struct clk_hw *hw)
 {
-	struct clk_pfd *pfd = to_clk_pfd(clk);
+	struct clk_pfd *pfd = to_clk_pfd(hw);
 
 	writel(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
 }
 
-static unsigned long clk_pfd_recalc_rate(struct clk *clk,
+static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_pfd *pfd = to_clk_pfd(clk);
+	struct clk_pfd *pfd = to_clk_pfd(hw);
 	u64 tmp = parent_rate;
 	u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
 
@@ -67,7 +67,7 @@ static unsigned long clk_pfd_recalc_rate(struct clk *clk,
 	return tmp;
 }
 
-static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
 	u64 tmp = *prate;
@@ -87,10 +87,10 @@ static long clk_pfd_round_rate(struct clk *clk, unsigned long rate,
 	return tmp;
 }
 
-static int clk_pfd_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_pfd *pfd = to_clk_pfd(clk);
+	struct clk_pfd *pfd = to_clk_pfd(hw);
 	u64 tmp = parent_rate;
 	u8 frac;
 
@@ -127,16 +127,16 @@ struct clk *imx_clk_pfd(const char *name, const char *parent,
 	pfd->reg = reg;
 	pfd->idx = idx;
 	pfd->parent = parent;
-	pfd->clk.name = name;
-	pfd->clk.ops = &clk_pfd_ops;
-	pfd->clk.parent_names = &pfd->parent;
-	pfd->clk.num_parents = 1;
+	pfd->hw.clk.name = name;
+	pfd->hw.clk.ops = &clk_pfd_ops;
+	pfd->hw.clk.parent_names = &pfd->parent;
+	pfd->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pfd->clk);
+	ret = bclk_register(&pfd->hw.clk);
 	if (ret) {
 		free(pfd);
 		return ERR_PTR(ret);
 	}
 
-	return &pfd->clk;
+	return &pfd->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 2842c740f9..bc837bd838 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -37,7 +37,7 @@
 #define LOCK_TIMEOUT_US		10000
 
 struct clk_pll14xx {
-	struct clk			clk;
+	struct clk_hw			hw;
 	void __iomem			*base;
 	enum imx_pll14xx_type		type;
 	const struct imx_pll14xx_rate_table *rate_table;
@@ -45,7 +45,7 @@ struct clk_pll14xx {
 	const char *parent;
 };
 
-#define to_clk_pll14xx(clk) container_of(clk, struct clk_pll14xx, clk)
+#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw)
 
 static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
 	PLL_1416X_RATE(1800000000U, 225, 3, 0),
@@ -92,10 +92,10 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
 	return NULL;
 }
 
-static long clk_pll14xx_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate,
 			unsigned long *prate)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	const struct imx_pll14xx_rate_table *rate_table = pll->rate_table;
 	int i;
 
@@ -108,10 +108,10 @@ static long clk_pll14xx_round_rate(struct clk *clk, unsigned long rate,
 	return rate_table[i - 1].rate;
 }
 
-static unsigned long clk_pll1416x_recalc_rate(struct clk *clk,
+static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	u32 mdiv, pdiv, sdiv, pll_div;
 	u64 fvco = parent_rate;
 
@@ -126,10 +126,10 @@ static unsigned long clk_pll1416x_recalc_rate(struct clk *clk,
 	return fvco;
 }
 
-static unsigned long clk_pll1443x_recalc_rate(struct clk *clk,
+static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
 	short int kdiv;
 	u64 fvco = parent_rate;
@@ -169,10 +169,10 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
 			LOCK_TIMEOUT_US);
 }
 
-static int clk_pll1416x_set_rate(struct clk *clk, unsigned long drate,
+static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
 				 unsigned long prate)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	const struct imx_pll14xx_rate_table *rate;
 	u32 tmp, div_val;
 	int ret;
@@ -180,7 +180,7 @@ static int clk_pll1416x_set_rate(struct clk *clk, unsigned long drate,
 	rate = imx_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-		       drate, clk->name);
+		       drate, hw->clk.name);
 		return -EINVAL;
 	}
 
@@ -239,7 +239,7 @@ int clk_pll1416x_early_set_rate(void __iomem *base, unsigned long drate,
 			  unsigned long prate)
 {
 	struct clk_pll14xx pll = {
-		.clk = {
+		.hw.clk = {
 			.name = "pll1416x",
 		},
 		.base = base,
@@ -247,13 +247,14 @@ int clk_pll1416x_early_set_rate(void __iomem *base, unsigned long drate,
 		.rate_count = ARRAY_SIZE(imx_pll1416x_tbl),
 	};
 
-	return clk_pll1416x_set_rate(&pll.clk, drate, prate);
+	return clk_pll1416x_set_rate(&pll.hw, drate, prate);
 }
 
-static int clk_pll1443x_set_rate(struct clk *clk, unsigned long drate,
+static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate,
 				 unsigned long prate)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
 	const struct imx_pll14xx_rate_table *rate;
 	u32 tmp, div_val;
 	int ret;
@@ -316,9 +317,9 @@ static int clk_pll1443x_set_rate(struct clk *clk, unsigned long drate,
 	return 0;
 }
 
-static int clk_pll14xx_prepare(struct clk *clk)
+static int clk_pll14xx_prepare(struct clk_hw *hw)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	u32 val;
 	int ret;
 
@@ -344,9 +345,9 @@ static int clk_pll14xx_prepare(struct clk *clk)
 	return 0;
 }
 
-static int clk_pll14xx_is_prepared(struct clk *clk)
+static int clk_pll14xx_is_prepared(struct clk_hw *hw)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	u32 val;
 
 	val = readl(pll->base + GNRL_CTL);
@@ -354,9 +355,9 @@ static int clk_pll14xx_is_prepared(struct clk *clk)
 	return (val & RST_MASK) ? 1 : 0;
 }
 
-static void clk_pll14xx_unprepare(struct clk *clk)
+static void clk_pll14xx_unprepare(struct clk_hw *hw)
 {
-	struct clk_pll14xx *pll = to_clk_pll14xx(clk);
+	struct clk_pll14xx *pll = to_clk_pll14xx(hw);
 	u32 val;
 
 	/*
@@ -403,7 +404,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
 	if (!pll)
 		return ERR_PTR(-ENOMEM);
 
-	clk = &pll->clk;
+	clk = &pll->hw.clk;
 
 	pll->parent = parent_name;
 	clk->name = name;
diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c
index 5654ed21b3..62afa2b6b2 100644
--- a/drivers/clk/imx/clk-pllv1.c
+++ b/drivers/clk/imx/clk-pllv1.c
@@ -17,7 +17,7 @@
 #define MFN_MASK	(MFN_SIGN - 1)
 
 struct clk_pllv1 {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	const char *parent;
 };
@@ -27,10 +27,10 @@ static inline bool mfn_is_negative(unsigned int mfn)
     return mfn & MFN_SIGN;
 }
 
-static unsigned long clk_pllv1_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_pllv1 *pll = container_of(clk, struct clk_pllv1, clk);
+	struct clk_pllv1 *pll = container_of(hw, struct clk_pllv1, hw);
 	unsigned long long ll;
 	int mfn_abs;
 	unsigned int mfi, mfn, mfd, pd;
@@ -79,16 +79,16 @@ struct clk *imx_clk_pllv1(const char *name, const char *parent,
 
 	pll->parent = parent;
 	pll->reg = base;
-	pll->clk.ops = &clk_pllv1_ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.ops = &clk_pllv1_ops;
+	pll->hw.clk.name = name;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
index 2b95be2495..d997e465d5 100644
--- a/drivers/clk/imx/clk-pllv2.c
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -70,7 +70,7 @@
 #define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
 
 struct clk_pllv2 {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	const char *parent;
 };
@@ -110,12 +110,12 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
 	return temp;
 }
 
-static unsigned long clk_pllv2_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
 	u32 dp_op, dp_mfd, dp_mfn, dp_ctl;
 	void __iomem *pllbase;
-	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+	struct clk_pllv2 *pll = container_of(hw, struct clk_pllv2, hw);
 
 	pllbase = pll->reg;
 
@@ -156,10 +156,10 @@ static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate,
 	return 0;
 }
 
-static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_pllv2 *pll = container_of(clk, struct clk_pllv2, clk);
+	struct clk_pllv2 *pll = container_of(hw, struct clk_pllv2, hw);
 	void __iomem *pllbase;
 	u32 dp_ctl, dp_op, dp_mfd, dp_mfn;
 	int ret;
@@ -181,7 +181,7 @@ static int clk_pllv2_set_rate(struct clk *clk, unsigned long rate,
 	return 0;
 }
 
-static long clk_pllv2_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long *prate)
 {
 	u32 dp_op, dp_mfd, dp_mfn;
@@ -205,16 +205,16 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
 
 	pll->parent = parent;
 	pll->reg = base;
-	pll->clk.ops = &clk_pllv2_ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.ops = &clk_pllv2_ops;
+	pll->hw.clk.name = name;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index e755f6b7e7..cb1d65058f 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -25,7 +25,7 @@
 #define IMX7_ENET_PLL_POWER	(0x1 << 5)
 
 struct clk_pllv3 {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*base;
 	bool		powerup_set;
 	u32		div_mask;
@@ -35,11 +35,11 @@ struct clk_pllv3 {
 	u32		power_bit;
 };
 
-#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
 
-static int clk_pllv3_enable(struct clk *clk)
+static int clk_pllv3_enable(struct clk_hw *hw)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	u32 val;
 	int timeout = 10000;
 
@@ -66,9 +66,9 @@ static int clk_pllv3_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_pllv3_disable(struct clk *clk)
+static void clk_pllv3_disable(struct clk_hw *hw)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	u32 val;
 
 	val = readl(pll->base);
@@ -82,16 +82,16 @@ static void clk_pllv3_disable(struct clk *clk)
 	writel(val, pll->base);
 }
 
-static unsigned long clk_pllv3_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
 					   unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
 
 	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
 }
 
-static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
 				 unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -100,10 +100,10 @@ static long clk_pllv3_round_rate(struct clk *clk, unsigned long rate,
 					    parent_rate * 20;
 }
 
-static int clk_pllv3_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	u32 val, div;
 
 	if (rate == parent_rate * 22)
@@ -129,16 +129,16 @@ static const struct clk_ops clk_pllv3_ops = {
 	.set_rate	= clk_pllv3_set_rate,
 };
 
-static unsigned long clk_pllv3_sys_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
 					       unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	u32 div = readl(pll->base) & pll->div_mask;
 
 	return parent_rate * div / 2;
 }
 
-static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -155,10 +155,10 @@ static long clk_pllv3_sys_round_rate(struct clk *clk, unsigned long rate,
 	return parent_rate * div / 2;
 }
 
-static int clk_pllv3_sys_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	unsigned long min_rate = parent_rate * 54 / 2;
 	unsigned long max_rate = parent_rate * 108 / 2;
 	u32 val, div;
@@ -183,10 +183,11 @@ static const struct clk_ops clk_pllv3_sys_ops = {
 	.set_rate	= clk_pllv3_sys_set_rate,
 };
 
-static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
 					      unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+
 	u32 mfn = readl(pll->base + PLL_NUM_OFFSET);
 	u32 mfd = readl(pll->base + PLL_DENOM_OFFSET);
 	u32 div = readl(pll->base) & pll->div_mask;
@@ -194,7 +195,7 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk *clk,
 	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
 }
 
-static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 				    unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -218,10 +219,11 @@ static long clk_pllv3_av_round_rate(struct clk *clk, unsigned long rate,
 	return parent_rate * div + parent_rate / mfd * mfn;
 }
 
-static int clk_pllv3_av_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 		unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
+
 	unsigned long min_rate = parent_rate * 27;
 	unsigned long max_rate = parent_rate * 54;
 	u32 val, div;
@@ -255,10 +257,10 @@ static const struct clk_ops clk_pllv3_av_ops = {
 	.set_rate	= clk_pllv3_av_set_rate,
 };
 
-static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
 						unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 
 	return pll->ref_clock;
 }
@@ -274,10 +276,10 @@ static const struct clk_ops clk_pllv3_mlb_ops = {
 	.disable	= clk_pllv3_disable,
 };
 
-static unsigned long clk_pllv3_sys_vf610_recalc_rate(struct clk *clk,
+static unsigned long clk_pllv3_sys_vf610_recalc_rate(struct clk_hw *hw,
 						     unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 
 	u32 mfn = readl(pll->base + SYS_VF610_PLL_OFFSET + PLL_NUM_OFFSET);
 	u32 mfd = readl(pll->base + SYS_VF610_PLL_OFFSET + PLL_DENOM_OFFSET);
@@ -286,7 +288,7 @@ static unsigned long clk_pllv3_sys_vf610_recalc_rate(struct clk *clk,
 	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
 }
 
-static long clk_pllv3_sys_vf610_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pllv3_sys_vf610_round_rate(struct clk_hw *hw, unsigned long rate,
 					   unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -308,10 +310,10 @@ static long clk_pllv3_sys_vf610_round_rate(struct clk *clk, unsigned long rate,
 	return parent_rate * 20 + parent_rate / mfd * mfn;
 }
 
-static int clk_pllv3_sys_vf610_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pllv3_sys_vf610_set_rate(struct clk_hw *hw, unsigned long rate,
 					unsigned long parent_rate)
 {
-	struct clk_pllv3 *pll = to_clk_pllv3(clk);
+	struct clk_pllv3 *pll = to_clk_pllv3(hw);
 	unsigned long min_rate = parent_rate * 20;
 	unsigned long max_rate = 528000000;
 	u32 val;
@@ -400,20 +402,20 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 	pll->base = base;
 	pll->div_mask = div_mask;
 	pll->parent = parent;
-	pll->clk.ops = ops;
-	pll->clk.name = name;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.ops = ops;
+	pll->hw.clk.name = name;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
 	val = readl(pll->base);
 	val &= ~BM_PLL_BYPASS;
 	writel(val, pll->base);
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
index 9fe4c6e6b2..f911bf4aa1 100644
--- a/drivers/clk/imx/clk-sccg-pll.c
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -39,26 +39,26 @@
 #define OSC_27M		27000000
 
 struct clk_sccg_pll {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*base;
 	const char	*parent;
 };
 
-#define to_clk_sccg_pll(_clk) container_of(_clk, struct clk_sccg_pll, clk)
+#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
 
-static int clk_pll1_is_prepared(struct clk *clk)
+static int clk_pll1_is_prepared(struct clk_hw *hw)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val;
 
 	val = readl(pll->base + PLL_CFG0);
 	return (val & (1 << PLL_PD)) ? 0 : 1;
 }
 
-static unsigned long clk_pll1_recalc_rate(struct clk *clk,
+static unsigned long clk_pll1_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val, divf;
 
 	val = readl(pll->base + PLL_CFG2);
@@ -67,7 +67,7 @@ static unsigned long clk_pll1_recalc_rate(struct clk *clk,
 	return parent_rate * 2 * (divf + 1);
 }
 
-static long clk_pll1_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pll1_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -78,10 +78,10 @@ static long clk_pll1_round_rate(struct clk *clk, unsigned long rate,
 	return parent_rate * div * 2;
 }
 
-static int clk_pll1_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pll1_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val;
 	u32 divf;
 
@@ -97,9 +97,9 @@ static int clk_pll1_set_rate(struct clk *clk, unsigned long rate,
 	return 0;
 }
 
-static int clk_pll1_prepare(struct clk *clk)
+static int clk_pll1_prepare(struct clk_hw *hw)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val;
 
 	val = readl(pll->base);
@@ -111,19 +111,20 @@ static int clk_pll1_prepare(struct clk *clk)
 	return 0;
 }
 
-static void clk_pll1_unprepare(struct clk *clk)
+static void clk_pll1_unprepare(struct clk_hw *hw)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val;
+
 	val = readl(pll->base);
 	val |= (1 << PLL_PD);
 	writel(val, pll->base);
 }
 
-static unsigned long clk_pll2_recalc_rate(struct clk *clk,
+static unsigned long clk_pll2_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val, ref, divr1, divf1, divr2, divf2;
 	u64 temp64;
 
@@ -154,7 +155,7 @@ static unsigned long clk_pll2_recalc_rate(struct clk *clk,
 	return (unsigned long)temp64;
 }
 
-static long clk_pll2_round_rate(struct clk *clk, unsigned long rate,
+static long clk_pll2_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
 	u32 div;
@@ -165,12 +166,12 @@ static long clk_pll2_round_rate(struct clk *clk, unsigned long rate,
 	return parent_rate * div;
 }
 
-static int clk_pll2_set_rate(struct clk *clk, unsigned long rate,
+static int clk_pll2_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
+	struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
 	u32 val;
 	u32 divf;
-	struct clk_sccg_pll *pll = to_clk_sccg_pll(clk);
 
 	divf = rate / (parent_rate);
 
@@ -210,25 +211,25 @@ struct clk *imx_clk_sccg_pll(const char *name, const char *parent_name,
 		return ERR_PTR(-ENOMEM);
 
 	pll->base = base;
-	pll->clk.name = name;
+	pll->hw.clk.name = name;
 	switch (pll_type) {
 	case SCCG_PLL1:
-		pll->clk.ops = &clk_sccg_pll1_ops;
+		pll->hw.clk.ops = &clk_sccg_pll1_ops;
 		break;
 	case SCCG_PLL2:
-		pll->clk.ops = &clk_sccg_pll2_ops;
+		pll->hw.clk.ops = &clk_sccg_pll2_ops;
 		break;
 	}
 
 	pll->parent = parent_name;
-        pll->clk.parent_names = &pll->parent;
-        pll->clk.num_parents = 1;
+        pll->hw.clk.parent_names = &pll->parent;
+        pll->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/loongson/clk-ls1b200.c b/drivers/clk/loongson/clk-ls1b200.c
index b7f4929423..6ac545224f 100644
--- a/drivers/clk/loongson/clk-ls1b200.c
+++ b/drivers/clk/loongson/clk-ls1b200.c
@@ -35,21 +35,21 @@ static struct clk *clks[LS1B_CLK_END];
 static struct clk_onecell_data clk_data;
 
 struct clk_ls1b200 {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *base;
 	int div_shift;
 	int div_mask;
 	const char *parent;
 };
 
-static unsigned long clk_ls1b200_recalc_rate(struct clk *clk, unsigned long parent_rate)
+static unsigned long clk_ls1b200_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
 	int n;
 	unsigned long rate;
 	int pll_freq;
 	struct clk_ls1b200 *ls1bclk;
 
-	ls1bclk = container_of(clk, struct clk_ls1b200, clk);
+	ls1bclk = container_of(hw, struct clk_ls1b200, hw);
 	pll_freq = __raw_readl(ls1bclk->base);
 
 	n  = 12 * 1024;
@@ -77,14 +77,14 @@ static struct clk *clk_ls1b200(const char *name, const char *parent,
 	f->div_shift = div_shift;
 	f->div_mask = div_mask;
 
-	f->clk.ops = &clk_ls1b200_ops;
-	f->clk.name = name;
-	f->clk.parent_names = &f->parent;
-	f->clk.num_parents = 1;
+	f->hw.clk.ops = &clk_ls1b200_ops;
+	f->hw.clk.name = name;
+	f->hw.clk.parent_names = &f->parent;
+	f->hw.clk.num_parents = 1;
 
-	bclk_register(&f->clk);
+	bclk_register(&f->hw.clk);
 
-	return &f->clk;
+	return &f->hw.clk;
 }
 
 static const char * const cpu_mux[] = {"cpu_div", "oscillator", };
diff --git a/drivers/clk/mvebu/corediv.c b/drivers/clk/mvebu/corediv.c
index 79e049d18c..1b7fa12701 100644
--- a/drivers/clk/mvebu/corediv.c
+++ b/drivers/clk/mvebu/corediv.c
@@ -51,7 +51,7 @@ struct clk_corediv_soc_desc {
  * existing in the current SoC.
  */
 struct clk_corediv {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	const struct clk_corediv_desc *desc;
 	const struct clk_corediv_soc_desc *soc_desc;
@@ -70,11 +70,11 @@ static const struct clk_corediv_desc mvebu_corediv_desc[] = {
 
 #define CORE_CLK_DIV_RATIO_MASK	0xff
 
-#define to_corediv_clk(p) container_of(p, struct clk_corediv, clk)
+#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
 
-static int clk_corediv_is_enabled(struct clk *clk)
+static int clk_corediv_is_enabled(struct clk_hw *hw)
 {
-	struct clk_corediv *corediv = to_corediv_clk(clk);
+	struct clk_corediv *corediv = to_corediv_clk(hw);
 	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
 	const struct clk_corediv_desc *desc = corediv->desc;
 	u32 enable_mask = BIT(desc->fieldbit) << soc_desc->enable_bit_offset;
@@ -82,9 +82,9 @@ static int clk_corediv_is_enabled(struct clk *clk)
 	return !!(readl(corediv->reg) & enable_mask);
 }
 
-static int clk_corediv_enable(struct clk *clk)
+static int clk_corediv_enable(struct clk_hw *hw)
 {
-	struct clk_corediv *corediv = to_corediv_clk(clk);
+	struct clk_corediv *corediv = to_corediv_clk(hw);
 	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
 	const struct clk_corediv_desc *desc = corediv->desc;
 	u32 reg;
@@ -96,9 +96,9 @@ static int clk_corediv_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_corediv_disable(struct clk *clk)
+static void clk_corediv_disable(struct clk_hw *hw)
 {
-	struct clk_corediv *corediv = to_corediv_clk(clk);
+	struct clk_corediv *corediv = to_corediv_clk(hw);
 	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
 	const struct clk_corediv_desc *desc = corediv->desc;
 	u32 reg;
@@ -108,10 +108,10 @@ static void clk_corediv_disable(struct clk *clk)
 	writel(reg, corediv->reg);
 }
 
-static unsigned long clk_corediv_recalc_rate(struct clk *clk,
+static unsigned long clk_corediv_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
-	struct clk_corediv *corediv = to_corediv_clk(clk);
+	struct clk_corediv *corediv = to_corediv_clk(hw);
 	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
 	const struct clk_corediv_desc *desc = corediv->desc;
 	u32 reg, div;
@@ -121,7 +121,7 @@ static unsigned long clk_corediv_recalc_rate(struct clk *clk,
 	return parent_rate / div;
 }
 
-static long clk_corediv_round_rate(struct clk *clk, unsigned long rate,
+static long clk_corediv_round_rate(struct clk_hw *hw, unsigned long rate,
 				   unsigned long *parent_rate)
 {
 	/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
@@ -136,10 +136,10 @@ static long clk_corediv_round_rate(struct clk *clk, unsigned long rate,
 	return *parent_rate / div;
 }
 
-static int clk_corediv_set_rate(struct clk *clk, unsigned long rate,
+static int clk_corediv_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
-	struct clk_corediv *corediv = to_corediv_clk(clk);
+	struct clk_corediv *corediv = to_corediv_clk(hw);
 	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
 	const struct clk_corediv_desc *desc = corediv->desc;
 	u32 reg, div;
@@ -225,7 +225,7 @@ static int mvebu_corediv_clk_probe(struct device_d *dev)
 
 	for (n = 0; n < clk_data.clk_num; n++) {
 		const char *clk_name;
-		struct clk *clk = &corediv->clk;
+		struct clk *clk = &corediv->hw.clk;
 
 		if (of_property_read_string_index(np,
 				"clock-output-names", n, &clk_name)) {
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
index 9bf48c2222..17083a051a 100644
--- a/drivers/clk/mxs/clk-div.c
+++ b/drivers/clk/mxs/clk-div.c
@@ -28,40 +28,40 @@ struct clk_div {
 	u8 busy;
 };
 
-static inline struct clk_div *to_clk_div(struct clk *clk)
+static inline struct clk_div *to_clk_div(struct clk_hw *hw)
 {
-	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
+	struct clk_divider *divider = to_clk_divider(hw);
 
 	return container_of(divider, struct clk_div, divider);
 }
 
-static unsigned long clk_div_recalc_rate(struct clk *clk,
+static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_div *div = to_clk_div(clk);
+	struct clk_div *div = to_clk_div(hw);
 
-	return div->ops->recalc_rate(&div->divider.clk, parent_rate);
+	return div->ops->recalc_rate(&div->divider.hw, parent_rate);
 }
 
-static long clk_div_round_rate(struct clk *clk, unsigned long rate,
+static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
-	struct clk_div *div = to_clk_div(clk);
+	struct clk_div *div = to_clk_div(hw);
 
-	return div->ops->round_rate(&div->divider.clk, rate, prate);
+	return div->ops->round_rate(&div->divider.hw, rate, prate);
 }
 
-static int clk_div_set_rate(struct clk *clk, unsigned long rate,
+static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_div *div = to_clk_div(clk);
+	struct clk_div *div = to_clk_div(hw);
 	int ret;
 
-	ret = div->ops->set_rate(&div->divider.clk, rate, parent_rate);
+	ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate);
 	if (ret)
 		return ret;
 
-	if (clk_is_enabled(clk))
+	if (clk_hw_is_enabled(hw))
 		while (readl(div->reg) & 1 << div->busy);
 
 	return 0;
@@ -82,10 +82,10 @@ struct clk *mxs_clk_div(const char *name, const char *parent_name,
 	div = xzalloc(sizeof(*div));
 
 	div->parent = parent_name;
-	div->divider.clk.name = name;
-	div->divider.clk.ops = &clk_div_ops;
-	div->divider.clk.parent_names = &div->parent;
-	div->divider.clk.num_parents = 1;
+	div->divider.hw.clk.name = name;
+	div->divider.hw.clk.ops = &clk_div_ops;
+	div->divider.hw.clk.parent_names = &div->parent;
+	div->divider.hw.clk.num_parents = 1;
 
 	div->reg = reg;
 	div->busy = busy;
@@ -96,9 +96,9 @@ struct clk *mxs_clk_div(const char *name, const char *parent_name,
 	div->divider.flags = CLK_DIVIDER_ONE_BASED;
 	div->ops = &clk_divider_ops;
 
-	ret = bclk_register(&div->divider.clk);
+	ret = bclk_register(&div->divider.hw.clk);
 	if (ret)
 		return ERR_PTR(ret);
 
-	return &div->divider.clk;
+	return &div->divider.hw.clk;
 }
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
index 6a6ce8c537..6fb479dfad 100644
--- a/drivers/clk/mxs/clk-frac.c
+++ b/drivers/clk/mxs/clk-frac.c
@@ -23,7 +23,7 @@
  * when the divider is adjusted.
  */
 struct clk_frac {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	void __iomem *reg;
 	u8 shift;
@@ -31,12 +31,12 @@ struct clk_frac {
 	u8 busy;
 };
 
-#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, clk)
+#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
 
-static unsigned long clk_frac_recalc_rate(struct clk *clk,
+static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
 					  unsigned long parent_rate)
 {
-	struct clk_frac *frac = to_clk_frac(clk);
+	struct clk_frac *frac = to_clk_frac(hw);
 	u32 div;
 
 	div = readl(frac->reg) >> frac->shift;
@@ -45,10 +45,10 @@ static unsigned long clk_frac_recalc_rate(struct clk *clk,
 	return (parent_rate >> frac->width) * div;
 }
 
-static long clk_frac_round_rate(struct clk *clk, unsigned long rate,
+static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate)
 {
-	struct clk_frac *frac = to_clk_frac(clk);
+	struct clk_frac *frac = to_clk_frac(hw);
 	unsigned long parent_rate = *prate;
 	u32 div;
 	u64 tmp;
@@ -67,10 +67,10 @@ static long clk_frac_round_rate(struct clk *clk, unsigned long rate,
 	return (parent_rate >> frac->width) * div;
 }
 
-static int clk_frac_set_rate(struct clk *clk, unsigned long rate,
+static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
 			     unsigned long parent_rate)
 {
-	struct clk_frac *frac = to_clk_frac(clk);
+	struct clk_frac *frac = to_clk_frac(hw);
 	u32 div, val;
 	u64 tmp;
 
@@ -90,7 +90,7 @@ static int clk_frac_set_rate(struct clk *clk, unsigned long rate,
 	val |= div << frac->shift;
 	writel(val, frac->reg);
 
-	if (clk_is_enabled(clk))
+	if (clk_hw_is_enabled(hw))
 		while (readl(frac->reg) & 1 << frac->busy);
 
 	return 0;
@@ -113,18 +113,18 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name,
 		return ERR_PTR(-ENOMEM);
 
 	frac->parent = parent_name;
-	frac->clk.name = name;
-	frac->clk.ops = &clk_frac_ops;
-	frac->clk.parent_names = &frac->parent;
-	frac->clk.num_parents = 1;
+	frac->hw.clk.name = name;
+	frac->hw.clk.ops = &clk_frac_ops;
+	frac->hw.clk.parent_names = &frac->parent;
+	frac->hw.clk.num_parents = 1;
 
 	frac->reg = reg;
 	frac->shift = shift;
 	frac->width = width;
 
-	ret = bclk_register(&frac->clk);
+	ret = bclk_register(&frac->hw.clk);
 	if (ret)
 		return ERR_PTR(ret);
 
-	return &frac->clk;
+	return &frac->hw.clk;
 }
diff --git a/drivers/clk/mxs/clk-lcdif.c b/drivers/clk/mxs/clk-lcdif.c
index 639f6eb6f4..a395701262 100644
--- a/drivers/clk/mxs/clk-lcdif.c
+++ b/drivers/clk/mxs/clk-lcdif.c
@@ -7,18 +7,18 @@
 #include "clk.h"
 
 struct clk_lcdif {
-	struct clk clk;
+	struct clk_hw hw;
 
 	struct clk *frac, *div, *gate;
 	const char *parent;
 };
 
-#define to_clk_lcdif(_hw) container_of(_hw, struct clk_lcdif, clk)
+#define to_clk_lcdif(_hw) container_of(_hw, struct clk_lcdif, hw)
 
-static int clk_lcdif_set_rate(struct clk *clk, unsigned long rate,
+static int clk_lcdif_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long unused)
 {
-	struct clk_lcdif *lcdif = to_clk_lcdif(clk);
+	struct clk_lcdif *lcdif = to_clk_lcdif(hw);
 	unsigned long frac, div, best_div = 1;
 	int delta, best_delta = 0x7fffffff;
 	unsigned long frate, rrate, best_frate;
@@ -63,14 +63,14 @@ struct clk *mxs_clk_lcdif(const char *name, struct clk *frac, struct clk *div,
 	lcdif->frac = frac;
 	lcdif->div = div;
 	lcdif->gate = gate;
-	lcdif->clk.name = name;
-	lcdif->clk.ops = &clk_lcdif_ops;
-	lcdif->clk.parent_names = &lcdif->parent;
-	lcdif->clk.num_parents = 1;
+	lcdif->hw.clk.name = name;
+	lcdif->hw.clk.ops = &clk_lcdif_ops;
+	lcdif->hw.clk.parent_names = &lcdif->parent;
+	lcdif->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&lcdif->clk);
+	ret = bclk_register(&lcdif->hw.clk);
 	if (ret)
 		return ERR_PTR(ret);
 
-	return &lcdif->clk;
+	return &lcdif->hw.clk;
 }
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
index 7094012a94..2c55ab7d8b 100644
--- a/drivers/clk/mxs/clk-pll.c
+++ b/drivers/clk/mxs/clk-pll.c
@@ -24,18 +24,18 @@
  * and the shift of gate bit is always 31.
  */
 struct clk_pll {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	void __iomem *base;
 	u8 power;
 	unsigned long rate;
 };
 
-#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, clk)
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
 
-static int clk_pll_enable(struct clk *clk)
+static int clk_pll_enable(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	writel(1 << pll->power, pll->base + SET);
 
@@ -46,18 +46,18 @@ static int clk_pll_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_pll_disable(struct clk *clk)
+static void clk_pll_disable(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	writel(1 << 31, pll->base + SET);
 
 	writel(1 << pll->power, pll->base + CLR);
 }
 
-static int clk_pll_is_enabled(struct clk *clk)
+static int clk_pll_is_enabled(struct clk_hw *hw)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 	u32 val;
 
 	val = readl(pll->base);
@@ -68,10 +68,10 @@ static int clk_pll_is_enabled(struct clk *clk)
 		return 1;
 }
 
-static unsigned long clk_pll_recalc_rate(struct clk *clk,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_pll *pll = to_clk_pll(clk);
+	struct clk_pll *pll = to_clk_pll(hw);
 
 	return pll->rate;
 }
@@ -92,18 +92,18 @@ struct clk *mxs_clk_pll(const char *name, const char *parent_name,
 	pll = xzalloc(sizeof(*pll));
 
 	pll->parent = parent_name;
-	pll->clk.name = name;
-	pll->clk.ops = &clk_pll_ops;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.name = name;
+	pll->hw.clk.ops = &clk_pll_ops;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
 	pll->base = base;
 	pll->rate = rate;
 	pll->power = power;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret)
 		ERR_PTR(ret);
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
index 8c12e282ad..d483c9c6b2 100644
--- a/drivers/clk/mxs/clk-ref.c
+++ b/drivers/clk/mxs/clk-ref.c
@@ -23,20 +23,20 @@
  * as pll rate  * (18 / FRAC), where FRAC = 18 ~ 35.
  */
 struct clk_ref {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	void __iomem *reg;
 	u8 idx;
 };
 
-#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, clk)
+#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, hw)
 
 #define SET	0x4
 #define CLR	0x8
 
-static int clk_ref_is_enabled(struct clk *clk)
+static int clk_ref_is_enabled(struct clk_hw *hw)
 {
-	struct clk_ref *ref = to_clk_ref(clk);
+	struct clk_ref *ref = to_clk_ref(hw);
 	u32 reg = readl(ref->reg);
 
 	if (reg & 1 << ((ref->idx + 1) * 8 - 1))
@@ -45,26 +45,26 @@ static int clk_ref_is_enabled(struct clk *clk)
 	return 1;
 }
 
-static int clk_ref_enable(struct clk *clk)
+static int clk_ref_enable(struct clk_hw *hw)
 {
-	struct clk_ref *ref = to_clk_ref(clk);
+	struct clk_ref *ref = to_clk_ref(hw);
 
 	writel(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
 
 	return 0;
 }
 
-static void clk_ref_disable(struct clk *clk)
+static void clk_ref_disable(struct clk_hw *hw)
 {
-	struct clk_ref *ref = to_clk_ref(clk);
+	struct clk_ref *ref = to_clk_ref(hw);
 
 	writel(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
 }
 
-static unsigned long clk_ref_recalc_rate(struct clk *clk,
+static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct clk_ref *ref = to_clk_ref(clk);
+	struct clk_ref *ref = to_clk_ref(hw);
 	u64 tmp = parent_rate;
 	u8 frac = (readl(ref->reg) >> (ref->idx * 8)) & 0x3f;
 
@@ -74,7 +74,7 @@ static unsigned long clk_ref_recalc_rate(struct clk *clk,
 	return tmp;
 }
 
-static long clk_ref_round_rate(struct clk *clk, unsigned long rate,
+static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long *prate)
 {
 	unsigned long parent_rate = *prate;
@@ -97,10 +97,10 @@ static long clk_ref_round_rate(struct clk *clk, unsigned long rate,
 	return tmp;
 }
 
-static int clk_ref_set_rate(struct clk *clk, unsigned long rate,
+static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	struct clk_ref *ref = to_clk_ref(clk);
+	struct clk_ref *ref = to_clk_ref(hw);
 	u64 tmp = parent_rate;
 	u32 val;
 	u32 frac, shift = ref->idx * 8;
@@ -140,17 +140,17 @@ struct clk *mxs_clk_ref(const char *name, const char *parent_name,
 	ref = xzalloc(sizeof(*ref));
 
 	ref->parent = parent_name;
-	ref->clk.name = name;
-	ref->clk.ops = &clk_ref_ops;
-	ref->clk.parent_names = &ref->parent;
-	ref->clk.num_parents = 1;
+	ref->hw.clk.name = name;
+	ref->hw.clk.ops = &clk_ref_ops;
+	ref->hw.clk.parent_names = &ref->parent;
+	ref->hw.clk.num_parents = 1;
 
 	ref->reg = reg;
 	ref->idx = idx;
 
-	ret = bclk_register(&ref->clk);
+	ret = bclk_register(&ref->hw.clk);
 	if (ret)
 		return ERR_PTR(ret);
 
-	return &ref->clk;
+	return &ref->hw.clk;
 }
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index 732ce4207d..88564872f5 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -48,7 +48,7 @@
  * @reg_data:	cpu-specific register settings
  */
 struct rockchip_cpuclk {
-	struct clk				hw;
+	struct clk_hw				hw;
 
 	struct clk				*alt_parent;
 	void __iomem				*reg_base;
@@ -57,9 +57,9 @@ struct rockchip_cpuclk {
 	const struct rockchip_cpuclk_reg_data	*reg_data;
 };
 
-#define to_rockchip_cpuclk_hw(hw) container_of(hw, struct rockchip_cpuclk, hw)
+#define to_rockchip_cpuclk_hw(_hw) container_of(_hw, struct rockchip_cpuclk, hw)
 
-static unsigned long rockchip_cpuclk_recalc_rate(struct clk *hw,
+static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
 					unsigned long parent_rate)
 {
 	struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_hw(hw);
@@ -94,13 +94,13 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 	if (!cpuclk)
 		return ERR_PTR(-ENOMEM);
 
-	cpuclk->hw.name = name;
-	cpuclk->hw.parent_names = &parent_names[0];
-	cpuclk->hw.num_parents = 1;
-	cpuclk->hw.ops = &rockchip_cpuclk_ops;
+	cpuclk->hw.clk.name = name;
+	cpuclk->hw.clk.parent_names = &parent_names[0];
+	cpuclk->hw.clk.num_parents = 1;
+	cpuclk->hw.clk.ops = &rockchip_cpuclk_ops;
 
 	/* only allow rate changes when we have a rate table */
-	cpuclk->hw.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0;
+	cpuclk->hw.clk.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0;
 
 	cpuclk->reg_base = reg_base;
 	cpuclk->reg_data = reg_data;
@@ -141,13 +141,13 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 		}
 	}
 
-	ret = bclk_register(&cpuclk->hw);
+	ret = bclk_register(&cpuclk->hw.clk);
 	if (ret) {
 		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
 		goto free_rate_table;
 	}
 
-	return &cpuclk->hw;
+	return &cpuclk->hw.clk;
 
 free_rate_table:
 	kfree(cpuclk->rate_table);
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index ec5b264ac5..9a430f928b 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -21,9 +21,9 @@
 #define PLL_MODE_DEEP		0x2
 
 struct rockchip_clk_pll {
-	struct clk		hw;
+	struct clk_hw		hw;
 
-	struct clk		pll_mux;
+	struct clk_hw		pll_mux;
 	const struct clk_ops	*pll_mux_ops;
 
 	void __iomem		*reg_base;
@@ -52,7 +52,7 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
 	return NULL;
 }
 
-static long rockchip_pll_round_rate(struct clk *hw,
+static long rockchip_pll_round_rate(struct clk_hw *hw,
 			    unsigned long drate, unsigned long *prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -112,7 +112,7 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3066_PLLCON3_PWRDOWN		(1 << 1)
 #define RK3066_PLLCON3_BYPASS		(1 << 0)
 
-static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk *hw,
+static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 						     unsigned long prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -122,7 +122,7 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk *hw,
 	pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
 	if (pllcon & RK3066_PLLCON3_BYPASS) {
 		pr_debug("%s: pll %s is bypassed\n", __func__,
-			__clk_get_name(hw));
+			clk_hw_get_name(hw));
 		return prate;
 	}
 
@@ -138,18 +138,18 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk *hw,
 	do_div(rate64, no + 1);
 
 	pr_debug("%s: %s rate=%lu\n",
-		 __func__, hw->name, (unsigned long)rate64);
+		 __func__, clk_hw_get_name(hw), (unsigned long)rate64);
 
 	return (unsigned long)rate64;
 }
 
-static int rockchip_rk3066_pll_set_rate(struct clk *hw, unsigned long drate,
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 					unsigned long prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 	const struct rockchip_pll_rate_table *rate;
 	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-	struct clk *pll_mux = &pll->pll_mux;
+	struct clk_hw *pll_mux = &pll->pll_mux;
 	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
 	int rate_change_remuxed = 0;
 	int cur_parent;
@@ -159,13 +159,13 @@ static int rockchip_rk3066_pll_set_rate(struct clk *hw, unsigned long drate,
 		return 0;
 
 	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
-		 __func__, __clk_get_name(hw), old_rate, drate, prate);
+		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
 
 	/* Get required rate settings from table */
 	rate = rockchip_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -215,7 +215,7 @@ static int rockchip_rk3066_pll_set_rate(struct clk *hw, unsigned long drate,
 	return ret;
 }
 
-static int rockchip_rk3066_pll_enable(struct clk *hw)
+static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 
@@ -225,7 +225,7 @@ static int rockchip_rk3066_pll_enable(struct clk *hw)
 	return 0;
 }
 
-static void rockchip_rk3066_pll_disable(struct clk *hw)
+static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 
@@ -234,7 +234,7 @@ static void rockchip_rk3066_pll_disable(struct clk *hw)
 	       pll->reg_base + RK3066_PLLCON(3));
 }
 
-static int rockchip_rk3066_pll_is_enabled(struct clk *hw)
+static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 	u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
@@ -290,10 +290,10 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 
 	/* name the actual pll */
 	snprintf(pll->pll_name, sizeof(pll->pll_name), "pll_%s", name);
-	pll->hw.name = pll->pll_name;
+	pll->hw.clk.name = pll->pll_name;
 
-	pll->hw.parent_names = &parent_names[0];
-	pll->hw.num_parents = 1;
+	pll->hw.clk.parent_names = &parent_names[0];
+	pll->hw.clk.num_parents = 1;
 
 	if (rate_table) {
 		int len;
@@ -315,9 +315,9 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	switch (pll_type) {
 	case pll_rk3066:
 		if (!pll->rate_table)
-			pll->hw.ops = &rockchip_rk3066_pll_clk_norate_ops;
+			pll->hw.clk.ops = &rockchip_rk3066_pll_clk_norate_ops;
 		else
-			pll->hw.ops = &rockchip_rk3066_pll_clk_ops;
+			pll->hw.clk.ops = &rockchip_rk3066_pll_clk_ops;
 		break;
 	default:
 		pr_warn("%s: Unknown pll type for pll clk %s\n",
@@ -330,11 +330,11 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	pll->lock_shift = lock_shift;
 	pll->flags = clk_pll_flags;
 
-	ret = bclk_register(&pll->hw);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		pr_err("%s: failed to register pll clock %s : %d\n",
 			__func__, name, ret);
-		mux_clk = &pll->hw;
+		mux_clk = &pll->hw.clk;
 		goto err_exit;
 	}
 
diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index 57459d0e2b..cbdec98fc6 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -14,15 +14,15 @@
 
 #include "clk.h"
 
-#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, clk)
+#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw)
 
 /* SDMMC Group for System Manager defines */
 #define SYSMGR_SDMMCGRP_CTRL_OFFSET	0x28
 
-static unsigned long socfpga_gate_clk_recalc_rate(struct clk *clk,
+static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hw,
 	unsigned long parent_rate)
 {
-	struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(clk);
+	struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hw);
 	u32 div = 1, val;
 
 	if (socfpgaclk->fixed_div)
@@ -36,9 +36,9 @@ static unsigned long socfpga_gate_clk_recalc_rate(struct clk *clk,
 	return parent_rate / div;
 }
 
-static int socfpga_clk_prepare(struct clk *clk)
+static int socfpga_clk_prepare(struct clk_hw *hw)
 {
-	struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(clk);
+	struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hw);
 	int i;
 	u32 hs_timing;
 	u32 clk_phase[2];
@@ -82,12 +82,12 @@ static int socfpga_clk_prepare(struct clk *clk)
 	return 0;
 }
 
-static int clk_socfpga_enable(struct clk *clk)
+static int clk_socfpga_enable(struct clk_hw *hw)
 {
-	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(clk);
+	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(hw);
 	u32 val;
 
-	socfpga_clk_prepare(clk);
+	socfpga_clk_prepare(hw);
 
 	val = readl(socfpga_clk->reg);
 	val |= 1 << socfpga_clk->bit_idx;
@@ -96,9 +96,9 @@ static int clk_socfpga_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_socfpga_disable(struct clk *clk)
+static void clk_socfpga_disable(struct clk_hw *hw)
 {
-	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(clk);
+	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(hw);
 	u32 val;
 
 	val = readl(socfpga_clk->reg);
@@ -159,8 +159,8 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
-	socfpga_clk->clk.name = xstrdup(clk_name);
-	socfpga_clk->clk.ops = ops;
+	socfpga_clk->hw.clk.name = xstrdup(clk_name);
+	socfpga_clk->hw.clk.ops = ops;
 
 	for (i = 0; i < SOCFPGA_MAX_PARENTS; i++) {
 		socfpga_clk->parent_names[i] = of_clk_get_parent_name(node, i);
@@ -168,16 +168,16 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 			break;
 	}
 
-	socfpga_clk->clk.num_parents = i;
-	socfpga_clk->clk.parent_names = socfpga_clk->parent_names;
+	socfpga_clk->hw.clk.num_parents = i;
+	socfpga_clk->hw.clk.parent_names = socfpga_clk->parent_names;
 
-	rc = bclk_register(&socfpga_clk->clk);
+	rc = bclk_register(&socfpga_clk->hw.clk);
 	if (rc) {
 		free(socfpga_clk);
 		return ERR_PTR(rc);
 	}
 
-	return &socfpga_clk->clk;
+	return &socfpga_clk->hw.clk;
 }
 
 struct clk *socfpga_a10_gate_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c
index 3fa636d990..f9cf40b0aa 100644
--- a/drivers/clk/socfpga/clk-periph-a10.c
+++ b/drivers/clk/socfpga/clk-periph-a10.c
@@ -17,12 +17,12 @@
 #define SOCFPGA_MPU_FREE_CLK		"mpu_free_clk"
 #define SOCFPGA_NOC_FREE_CLK		"noc_free_clk"
 #define SOCFPGA_SDMMC_FREE_CLK		"sdmmc_free_clk"
-#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, clk)
+#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw)
 
-static unsigned long clk_periclk_recalc_rate(struct clk *clk,
+static unsigned long clk_periclk_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
-	struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(clk);
+	struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hw);
 	u32 div;
 
 	if (socfpgaclk->fixed_div) {
@@ -38,15 +38,15 @@ static unsigned long clk_periclk_recalc_rate(struct clk *clk,
 	return parent_rate / div;
 }
 
-static int clk_periclk_get_parent(struct clk *clk)
+static int clk_periclk_get_parent(struct clk_hw *hw)
 {
-	struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(clk);
+	struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hw);
 	u32 clk_src;
 
 	clk_src = readl(socfpgaclk->reg);
-	if (streq(clk->name, SOCFPGA_MPU_FREE_CLK) ||
-	    streq(clk->name, SOCFPGA_NOC_FREE_CLK) ||
-	    streq(clk->name, SOCFPGA_SDMMC_FREE_CLK))
+	if (streq(clk_hw_get_name(hw), SOCFPGA_MPU_FREE_CLK) ||
+	    streq(clk_hw_get_name(hw), SOCFPGA_NOC_FREE_CLK) ||
+	    streq(clk_hw_get_name(hw), SOCFPGA_SDMMC_FREE_CLK))
 		return (clk_src >> CLK_MGR_FREE_SHIFT) &
 			CLK_MGR_FREE_MASK;
 	else
@@ -98,19 +98,19 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 			break;
 	}
 
-	periph_clk->clk.num_parents = i;
-	periph_clk->clk.parent_names = periph_clk->parent_names;
+	periph_clk->hw.clk.num_parents = i;
+	periph_clk->hw.clk.parent_names = periph_clk->parent_names;
 
-	periph_clk->clk.name = xstrdup(clk_name);
-	periph_clk->clk.ops = ops;
+	periph_clk->hw.clk.name = xstrdup(clk_name);
+	periph_clk->hw.clk.ops = ops;
 
-	rc = bclk_register(&periph_clk->clk);
+	rc = bclk_register(&periph_clk->hw.clk);
 	if (rc) {
 		free(periph_clk);
 		return ERR_PTR(rc);
 	}
 
-	return &periph_clk->clk;
+	return &periph_clk->hw.clk;
 }
 
 struct clk *socfpga_a10_periph_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index e0c34d8486..2e58a2eb5d 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -28,12 +28,12 @@
 #define SOCFPGA_MAIN_PLL_CLK		"main_pll"
 #define SOCFPGA_PERIP_PLL_CLK		"periph_pll"
 
-#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, clk)
+#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw)
 
-static unsigned long clk_pll_recalc_rate(struct clk *clk,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
-	struct socfpga_pll *socfpgaclk = to_socfpga_clk(clk);
+	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hw);
 	unsigned long divf, divq, reg;
 	unsigned long long vco_freq;
 
@@ -46,9 +46,9 @@ static unsigned long clk_pll_recalc_rate(struct clk *clk,
 	return (unsigned long)vco_freq;
 }
 
-static int clk_pll_get_parent(struct clk *clk)
+static int clk_pll_get_parent(struct clk_hw *hw)
 {
-	struct socfpga_pll *socfpgaclk = to_socfpga_clk(clk);
+	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hw);
 	u32 pll_src;
 
 	pll_src = readl(socfpgaclk->reg);
@@ -57,9 +57,9 @@ static int clk_pll_get_parent(struct clk *clk)
 		CLK_MGR_PLL_CLK_SRC_MASK;
 }
 
-static int clk_socfpga_enable(struct clk *clk)
+static int clk_socfpga_enable(struct clk_hw *hw)
 {
-	struct socfpga_pll *socfpga_clk = to_socfpga_clk(clk);
+	struct socfpga_pll *socfpga_clk = to_socfpga_clk(hw);
 	u32 val;
 
 	val = readl(socfpga_clk->reg);
@@ -69,9 +69,9 @@ static int clk_socfpga_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_socfpga_disable(struct clk *clk)
+static void clk_socfpga_disable(struct clk_hw *hw)
 {
-	struct socfpga_pll *socfpga_clk = to_socfpga_clk(clk);
+	struct socfpga_pll *socfpga_clk = to_socfpga_clk(hw);
 	u32 val;
 
 	val = readl(socfpga_clk->reg);
@@ -101,8 +101,8 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
-	pll_clk->clk.name = xstrdup(clk_name);
-	pll_clk->clk.ops = ops;
+	pll_clk->hw.clk.name = xstrdup(clk_name);
+	pll_clk->hw.clk.ops = ops;
 
 	for (i = 0; i < SOCFPGA_MAX_PARENTS; i++) {
 		pll_clk->parent_names[i] = of_clk_get_parent_name(node, i);
@@ -111,19 +111,19 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 	}
 
 	pll_clk->bit_idx = SOCFPGA_PLL_EXT_ENA;
-	pll_clk->clk.num_parents = i;
-	pll_clk->clk.parent_names = pll_clk->parent_names;
+	pll_clk->hw.clk.num_parents = i;
+	pll_clk->hw.clk.parent_names = pll_clk->parent_names;
 
 	clk_pll_ops.enable = clk_socfpga_enable;
 	clk_pll_ops.disable = clk_socfpga_disable;
 
-	rc = bclk_register(&pll_clk->clk);
+	rc = bclk_register(&pll_clk->hw.clk);
 	if (rc) {
 		free(pll_clk);
 		return NULL;
 	}
 
-	return &pll_clk->clk;
+	return &pll_clk->hw.clk;
 }
 
 struct clk *socfpga_a10_pll_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index bdc8023820..8ee405c6c6 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -50,15 +50,15 @@
 void __iomem *clk_mgr_base_addr;
 
 struct clk_pll {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	unsigned regofs;
 };
 
-static unsigned long clk_pll_recalc_rate(struct clk *clk,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_pll *pll = container_of(clk, struct clk_pll, clk);
+	struct clk_pll *pll = container_of(hw, struct clk_pll, hw);
 	unsigned long divf, divq, vco_freq, reg;
 	unsigned long bypass;
 
@@ -90,24 +90,24 @@ static struct clk *socfpga_pll_clk(struct device_node *node)
 	if (!pll->parent)
 		return ERR_PTR(-EINVAL);
 
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
-	pll->clk.name = xstrdup(node->name);
-	pll->clk.ops = &clk_pll_ops;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
+	pll->hw.clk.name = xstrdup(node->name);
+	pll->hw.clk.ops = &clk_pll_ops;
 
 	of_property_read_u32(node, "reg", &pll->regofs);
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
 
 struct clk_periph {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	unsigned regofs;
 	unsigned int fixed_div;
@@ -116,10 +116,10 @@ struct clk_periph {
 	unsigned int shift;
 };
 
-static unsigned long clk_periph_recalc_rate(struct clk *clk,
+static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
-	struct clk_periph *periph = container_of(clk, struct clk_periph, clk);
+	struct clk_periph *periph = container_of(hw, struct clk_periph, hw);
 	u32 div, val;
 
 	if (periph->fixed_div) {
@@ -152,10 +152,10 @@ static struct clk *socfpga_periph_clk(struct device_node *node)
 	if (!periph->parent)
 		return ERR_PTR(-EINVAL);
 
-	periph->clk.parent_names = &periph->parent;
-	periph->clk.num_parents = 1;
-	periph->clk.name = xstrdup(node->name);
-	periph->clk.ops = &clk_periph_ops;
+	periph->hw.clk.parent_names = &periph->parent;
+	periph->hw.clk.num_parents = 1;
+	periph->hw.clk.name = xstrdup(node->name);
+	periph->hw.clk.ops = &clk_periph_ops;
 
 	ret = of_property_read_u32_array(node, "div-reg", div_reg, 3);
 	if (!ret) {
@@ -169,17 +169,17 @@ static struct clk *socfpga_periph_clk(struct device_node *node)
 	of_property_read_u32(node, "reg", &periph->regofs);
 	of_property_read_u32(node, "fixed-divider", &periph->fixed_div);
 
-	ret = bclk_register(&periph->clk);
+	ret = bclk_register(&periph->hw.clk);
 	if (ret) {
 		free(periph);
 		return ERR_PTR(ret);
 	}
 
-	return &periph->clk;
+	return &periph->hw.clk;
 }
 
 struct clk_socfpga {
-	struct clk clk;
+	struct clk_hw hw;
 	const char *parent;
 	void __iomem *reg;
 	void __iomem *div_reg;
@@ -190,9 +190,9 @@ struct clk_socfpga {
 	const char *parent_names[SOCFGPA_MAX_PARENTS];
 };
 
-static int clk_socfpga_enable(struct clk *clk)
+static int clk_socfpga_enable(struct clk_hw *hw)
 {
-	struct clk_socfpga *cs = container_of(clk, struct clk_socfpga, clk);
+	struct clk_socfpga *cs = container_of(hw, struct clk_socfpga, hw);
 	u32 val;
 
 	val = readl(cs->reg);
@@ -202,9 +202,9 @@ static int clk_socfpga_enable(struct clk *clk)
 	return 0;
 }
 
-static void clk_socfpga_disable(struct clk *clk)
+static void clk_socfpga_disable(struct clk_hw *hw)
 {
-	struct clk_socfpga *cs = container_of(clk, struct clk_socfpga, clk);
+	struct clk_socfpga *cs = container_of(hw, struct clk_socfpga, hw);
 	u32 val;
 
 	val = readl(cs->reg);
@@ -212,9 +212,9 @@ static void clk_socfpga_disable(struct clk *clk)
 	writel(val, cs->reg);
 }
 
-static int clk_socfpga_is_enabled(struct clk *clk)
+static int clk_socfpga_is_enabled(struct clk_hw *hw)
 {
-	struct clk_socfpga *cs = container_of(clk, struct clk_socfpga, clk);
+	struct clk_socfpga *cs = container_of(hw, struct clk_socfpga, hw);
 	u32 val;
 
 	val = readl(cs->reg);
@@ -225,10 +225,10 @@ static int clk_socfpga_is_enabled(struct clk *clk)
 		return 0;
 }
 
-static unsigned long clk_socfpga_recalc_rate(struct clk *clk,
+static unsigned long clk_socfpga_recalc_rate(struct clk_hw *hw,
 	unsigned long parent_rate)
 {
-	struct clk_socfpga *cs = container_of(clk, struct clk_socfpga, clk);
+	struct clk_socfpga *cs = container_of(hw, struct clk_socfpga, hw);
 	u32 div = 1, val;
 
 	if (cs->fixed_div) {
@@ -236,7 +236,7 @@ static unsigned long clk_socfpga_recalc_rate(struct clk *clk,
 	} else if (cs->div_reg) {
 		val = readl(cs->div_reg) >> cs->shift;
 		val &= div_mask(cs->width);
-		if (streq(clk->name, SOCFPGA_DB_CLK))
+		if (streq(clk_hw_get_name(hw), SOCFPGA_DB_CLK))
 			div = val + 1;
 		else
 			div = (1 << val);
@@ -245,8 +245,9 @@ static unsigned long clk_socfpga_recalc_rate(struct clk *clk,
 	return parent_rate / div;
 }
 
-static int clk_socfpga_get_parent(struct clk *clk)
+static int clk_socfpga_get_parent(struct clk_hw *hw)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	u32 perpll_src;
 	u32 l4_src;
 
@@ -270,8 +271,9 @@ static int clk_socfpga_get_parent(struct clk *clk)
 	return (perpll_src >> 4) & 3;
 }
 
-static int clk_socfpga_set_parent(struct clk *clk, u8 parent)
+static int clk_socfpga_set_parent(struct clk_hw *hw, u8 parent)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	u32 src_reg;
 
 	if (streq(clk->name, SOCFPGA_L4_MP_CLK)) {
@@ -351,18 +353,18 @@ static struct clk *socfpga_gate_clk(struct device_node *node)
 			break;
 	}
 
-	cs->clk.parent_names = cs->parent_names;
-	cs->clk.num_parents = i;
-	cs->clk.name = xstrdup(node->name);
-	cs->clk.ops = &clk_socfpga_ops;
+	cs->hw.clk.parent_names = cs->parent_names;
+	cs->hw.clk.num_parents = i;
+	cs->hw.clk.name = xstrdup(node->name);
+	cs->hw.clk.ops = &clk_socfpga_ops;
 
-	ret = bclk_register(&cs->clk);
+	ret = bclk_register(&cs->hw.clk);
 	if (ret) {
 		free(cs);
 		return ERR_PTR(ret);
 	}
 
-	return &cs->clk;
+	return &cs->hw.clk;
 }
 
 static void socfpga_register_clocks(struct device_d *dev, struct device_node *node)
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index 9d291f7243..402f714436 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -47,14 +47,14 @@ static inline struct clk *socfpga_a10_gate_init(struct device_node *node)
 #endif
 
 struct socfpga_pll {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	u32 bit_idx;
 	const char *parent_names[SOCFPGA_MAX_PARENTS];
 };
 
 struct socfpga_gate_clk {
-	struct clk clk;
+	struct clk_hw hw;
 	char *parent_name;
 	u32 fixed_div;
 	void __iomem *div_reg;
@@ -68,7 +68,7 @@ struct socfpga_gate_clk {
 };
 
 struct socfpga_periph_clk {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	char *parent_name;
 	u32 fixed_div;
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index 57868186d3..1377d5a1ac 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -57,10 +57,11 @@ static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
 	return divider_ux1;
 }
 
-static unsigned long clk_frac_div_recalc_rate(struct clk *hw,
+static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
-	struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct tegra_clk_frac_div *divider = to_clk_frac_div(clk);
 	u32 reg;
 	int div, mul;
 	u64 rate = parent_rate;
@@ -78,10 +79,11 @@ static unsigned long clk_frac_div_recalc_rate(struct clk *hw,
 	return rate;
 }
 
-static long clk_frac_div_round_rate(struct clk *hw, unsigned long rate,
+static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate,
 				   unsigned long *prate)
 {
-	struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct tegra_clk_frac_div *divider = to_clk_frac_div(clk);
 	int div, mul;
 	unsigned long output_rate = *prate;
 
@@ -97,10 +99,11 @@ static long clk_frac_div_round_rate(struct clk *hw, unsigned long rate,
 	return DIV_ROUND_UP(output_rate * mul, div + mul);
 }
 
-static int clk_frac_div_set_rate(struct clk *hw, unsigned long rate,
+static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
-	struct tegra_clk_frac_div *divider = to_clk_frac_div(hw);
+	struct clk *clk = clk_hw_to_clk(hw);
+	struct tegra_clk_frac_div *divider = to_clk_frac_div(clk);
 	int div;
 	u32 val;
 
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 6ed54169ad..7bfb14875d 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -16,65 +16,65 @@
 
 #define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw)
 
-static int clk_periph_get_parent(struct clk *hw)
+static int clk_periph_get_parent(struct clk_hw *hw)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->mux->ops->get_parent(periph->mux);
+	return periph->mux->ops->get_parent(clk_to_clk_hw(periph->mux));
 }
 
-static int clk_periph_set_parent(struct clk *hw, u8 index)
+static int clk_periph_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->mux->ops->set_parent(periph->mux, index);
+	return periph->mux->ops->set_parent(clk_to_clk_hw(periph->mux), index);
 }
 
-static unsigned long clk_periph_recalc_rate(struct clk *hw,
+static unsigned long clk_periph_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->div->ops->recalc_rate(periph->div, parent_rate);
+	return periph->div->ops->recalc_rate(clk_to_clk_hw(periph->div), parent_rate);
 }
 
-static long clk_periph_round_rate(struct clk *hw, unsigned long rate,
+static long clk_periph_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *prate)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->div->ops->round_rate(periph->div, rate, prate);
+	return periph->div->ops->round_rate(clk_to_clk_hw(periph->div), rate, prate);
 }
 
-static int clk_periph_set_rate(struct clk *hw, unsigned long rate,
+static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->div->ops->set_rate(periph->div, rate, parent_rate);
+	return periph->div->ops->set_rate(clk_to_clk_hw(periph->div), rate, parent_rate);
 }
 
-static int clk_periph_is_enabled(struct clk *hw)
+static int clk_periph_is_enabled(struct clk_hw *hw)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	return periph->gate->ops->is_enabled(periph->gate);
+	return periph->gate->ops->is_enabled(clk_to_clk_hw(periph->gate));
 }
 
-static int clk_periph_enable(struct clk *hw)
+static int clk_periph_enable(struct clk_hw *hw)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	periph->gate->ops->enable(periph->gate);
+	periph->gate->ops->enable(clk_to_clk_hw(periph->gate));
 
 	return 0;
 }
 
-static void clk_periph_disable(struct clk *hw)
+static void clk_periph_disable(struct clk_hw *hw)
 {
 	struct tegra_clk_periph *periph = to_clk_periph(hw);
 
-	periph->gate->ops->disable(periph->gate);
+	periph->gate->ops->disable(clk_to_clk_hw(periph->gate));
 }
 
 const struct clk_ops tegra_clk_periph_ops = {
@@ -139,11 +139,11 @@ static struct clk *_tegra_clk_register_periph(const char *name,
 			goto out_div;
 	}
 
-	periph->hw.name = name;
-	periph->hw.ops = div ? &tegra_clk_periph_ops :
+	periph->hw.clk.name = name;
+	periph->hw.clk.ops = div ? &tegra_clk_periph_ops :
 				   &tegra_clk_periph_nodiv_ops;
-	periph->hw.parent_names = parent_names;
-	periph->hw.num_parents = num_parents;
+	periph->hw.clk.parent_names = parent_names;
+	periph->hw.clk.num_parents = num_parents;
 	periph->flags = flags;
 
 	if (id >= 96)
@@ -153,11 +153,11 @@ static struct clk *_tegra_clk_register_periph(const char *name,
 	periph->rst_reg = clk_base + rst_offs;
 	periph->rst_shift = id & 0x1f;
 
-	ret = bclk_register(&periph->hw);
+	ret = bclk_register(&periph->hw.clk);
 	if (ret)
 		goto out_register;
 
-	return &periph->hw;
+	return &periph->hw.clk;
 
 out_register:
 	tegra_clk_divider_free(periph->div);
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c
index 4b48fa2d64..f14b41c04a 100644
--- a/drivers/clk/tegra/clk-pll-out.c
+++ b/drivers/clk/tegra/clk-pll-out.c
@@ -18,7 +18,7 @@
 
 #define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
 
-static int clk_pll_out_is_enabled(struct clk *hw)
+static int clk_pll_out_is_enabled(struct clk_hw *hw)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 	u32 val = readl(pll_out->reg);
@@ -30,7 +30,7 @@ static int clk_pll_out_is_enabled(struct clk *hw)
 	return state;
 }
 
-static int clk_pll_out_enable(struct clk *hw)
+static int clk_pll_out_enable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 	u32 val;
@@ -45,7 +45,7 @@ static int clk_pll_out_enable(struct clk *hw)
 	return 0;
 }
 
-static void clk_pll_out_disable(struct clk *hw)
+static void clk_pll_out_disable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 	u32 val;
@@ -58,28 +58,28 @@ static void clk_pll_out_disable(struct clk *hw)
 	udelay(2);
 }
 
-static unsigned long clk_pll_out_recalc_rate(struct clk *hw,
+static unsigned long clk_pll_out_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 
-	return pll_out->div->ops->recalc_rate(pll_out->div, parent_rate);
+	return pll_out->div->ops->recalc_rate(clk_to_clk_hw(pll_out->div), parent_rate);
 }
 
-static long clk_pll_out_round_rate(struct clk *hw, unsigned long rate,
+static long clk_pll_out_round_rate(struct clk_hw *hw, unsigned long rate,
 				   unsigned long *prate)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 
-	return pll_out->div->ops->round_rate(pll_out->div, rate, prate);
+	return pll_out->div->ops->round_rate(clk_to_clk_hw(pll_out->div), rate, prate);
 }
 
-static int clk_pll_out_set_rate(struct clk *hw, unsigned long rate,
+static int clk_pll_out_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
 	struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
 
-	return pll_out->div->ops->set_rate(pll_out->div, rate, parent_rate);
+	return pll_out->div->ops->set_rate(clk_to_clk_hw(pll_out->div), rate, parent_rate);
 }
 
 const struct clk_ops tegra_clk_pll_out_ops = {
@@ -108,21 +108,21 @@ struct clk *tegra_clk_register_pll_out(const char *name,
 	}
 
 	pll_out->parent = parent_name;
-	pll_out->hw.name = name;
-	pll_out->hw.ops = &tegra_clk_pll_out_ops;
-	pll_out->hw.parent_names = (pll_out->parent ? &pll_out->parent : NULL);
-	pll_out->hw.num_parents = (pll_out->parent ? 1 : 0);
+	pll_out->hw.clk.name = name;
+	pll_out->hw.clk.ops = &tegra_clk_pll_out_ops;
+	pll_out->hw.clk.parent_names = (pll_out->parent ? &pll_out->parent : NULL);
+	pll_out->hw.clk.num_parents = (pll_out->parent ? 1 : 0);
 
 	pll_out->reg = reg;
 	pll_out->enb_bit_idx = shift + 1;
 	pll_out->rst_bit_idx = shift;
 
-	ret = bclk_register(&pll_out->hw);
+	ret = bclk_register(&pll_out->hw.clk);
 	if (ret) {
 		tegra_clk_divider_free(pll_out->div);
 		kfree(pll_out);
 		return ERR_PTR(ret);
 	}
 
-	return &pll_out->hw;
+	return &pll_out->hw.clk;
 }
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 4b04876df1..0d364f318d 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -144,7 +144,7 @@
 
 #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
 
-static int clk_pll_is_enabled(struct clk *hw)
+static int clk_pll_is_enabled(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	u32 val;
@@ -187,12 +187,12 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll,
 	}
 
 	pr_err("%s: Timed out waiting for pll %s lock\n", __func__,
-	       pll->hw.name);
+	       clk_hw_get_name(&pll->hw));
 
 	return -1;
 }
 
-static int clk_pll_enable(struct clk *hw)
+static int clk_pll_enable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	u32 val;
@@ -210,7 +210,7 @@ static int clk_pll_enable(struct clk *hw)
 	return 0;
 }
 
-static void clk_pll_disable(struct clk *hw)
+static void clk_pll_disable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	u32 val;
@@ -220,7 +220,7 @@ static void clk_pll_disable(struct clk *hw)
 	pll_writel_base(val, pll);
 }
 
-static int _get_table_rate(struct clk *hw,
+static int _get_table_rate(struct clk_hw *hw,
 			   struct tegra_clk_pll_freq_table *cfg,
 			   unsigned long rate, unsigned long parent_rate)
 {
@@ -245,7 +245,7 @@ static int _get_table_rate(struct clk *hw,
 	return 0;
 }
 
-static unsigned long clk_pll_recalc_rate(struct clk *hw,
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -260,7 +260,7 @@ static unsigned long clk_pll_recalc_rate(struct clk *hw,
 		struct tegra_clk_pll_freq_table sel;
 		if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) {
 			pr_err("Clock %s has unknown fixed frequency\n",
-			       hw->name);
+			       clk_hw_get_name(hw));
 			BUG();
 		}
 		return pll->fixed_rate;
@@ -280,7 +280,7 @@ static unsigned long clk_pll_recalc_rate(struct clk *hw,
 	return rate;
 }
 
-static int _calc_rate(struct clk *hw, struct tegra_clk_pll_freq_table *cfg,
+static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
 		      unsigned long rate, unsigned long parent_rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -325,14 +325,14 @@ static int _calc_rate(struct clk *hw, struct tegra_clk_pll_freq_table *cfg,
 	if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
 	    cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) {
 		pr_err("%s: Failed to set %s rate %lu\n",
-		       __func__, hw->name, rate);
+		       __func__, clk_hw_get_name(hw), rate);
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static long clk_pll_round_rate(struct clk *hw, unsigned long rate,
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 			unsigned long *prate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -344,7 +344,7 @@ static long clk_pll_round_rate(struct clk *hw, unsigned long rate,
 
 	/* PLLM is used for memory; we do not change rate */
 	if (pll->flags & TEGRA_PLLM)
-		return clk_get_rate(hw);
+		return clk_get_rate(clk_hw_to_clk(hw));
 
 	if (_get_table_rate(hw, &cfg, rate, *prate) &&
 	    _calc_rate(hw, &cfg, rate, *prate))
@@ -356,7 +356,7 @@ static long clk_pll_round_rate(struct clk *hw, unsigned long rate,
 	return output_rate;
 }
 
-static int _program_pll(struct clk *hw, struct tegra_clk_pll_freq_table *cfg,
+static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
 			unsigned long rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -411,7 +411,7 @@ static int _program_pll(struct clk *hw, struct tegra_clk_pll_freq_table *cfg,
 	return 0;
 }
 
-static int clk_pll_set_rate(struct clk *hw, unsigned long rate,
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			unsigned long parent_rate)
 {
 	struct tegra_clk_pll_freq_table cfg;
@@ -432,7 +432,7 @@ const struct clk_ops tegra_clk_pll_ops = {
 	.set_rate = clk_pll_set_rate,
 };
 
-static unsigned long clk_plle_recalc_rate(struct clk *hw,
+static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -474,10 +474,10 @@ static int clk_plle_training(struct tegra_clk_pll *pll)
 			(pll_readl_misc(pll) & PLLE_MISC_READY));
 }
 
-static int clk_plle_enable(struct clk *hw)
+static int clk_plle_enable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
-	unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+	unsigned long input_rate = clk_get_rate(clk_get_parent(clk_hw_to_clk(hw)));
 	struct tegra_clk_pll_freq_table sel;
 	u32 val;
 	int err;
@@ -534,10 +534,10 @@ const struct clk_ops tegra_clk_plle_ops = {
 	.enable = clk_plle_enable,
 };
 
-static int clk_plle_tegra114_enable(struct clk *hw)
+static int clk_plle_tegra114_enable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
-	unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+	unsigned long input_rate = clk_get_rate(clk_get_parent(clk_hw_to_clk(hw)));
 	struct tegra_clk_pll_freq_table sel;
 	u32 val;
 	int ret;
@@ -623,7 +623,7 @@ static int clk_plle_tegra114_enable(struct clk *hw)
 	return ret;
 }
 
-static void clk_plle_tegra114_disable(struct clk *hw)
+static void clk_plle_tegra114_disable(struct clk_hw *hw)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	u32 val;
@@ -658,11 +658,11 @@ static struct clk *_tegra_clk_register_pll(const char *name,
 		return NULL;
 
 	pll->parent = parent_name;
-	pll->hw.name = name;
-	pll->hw.ops = ops;
-	pll->hw.flags = flags;
-	pll->hw.parent_names = (pll->parent ? &pll->parent : NULL);
-	pll->hw.num_parents = (pll->parent ? 1 : 0);
+	pll->hw.clk.name = name;
+	pll->hw.clk.ops = ops;
+	pll->hw.clk.flags = flags;
+	pll->hw.clk.parent_names = (pll->parent ? &pll->parent : NULL);
+	pll->hw.clk.num_parents = (pll->parent ? 1 : 0);
 
 	pll->clk_base = clk_base;
 
@@ -678,13 +678,13 @@ static struct clk *_tegra_clk_register_pll(const char *name,
 	pll->divm_shift = PLL_BASE_DIVM_SHIFT;
 	pll->divm_width = PLL_BASE_DIVM_WIDTH;
 
-	ret = bclk_register(&pll->hw);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->hw;
+	return &pll->hw.clk;
 }
 
 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 5195e6dba4..80a83c7865 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -61,7 +61,7 @@ struct tegra_clk_pll_params {
 
 /* struct tegra_clk_pll - Tegra PLL clock */
 struct tegra_clk_pll {
-	struct clk	hw;
+	struct clk_hw	hw;
 	void __iomem	*clk_base;
 	u8		flags;
 	unsigned long	fixed_rate;
@@ -105,7 +105,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
 
 /* struct tegra_clk_pll_out - PLL output divider */
 struct tegra_clk_pll_out {
-	struct clk	hw;
+	struct clk_hw	hw;
 	struct clk	*div;
 	void __iomem	*reg;
 	u8		enb_bit_idx;
@@ -119,7 +119,7 @@ struct clk *tegra_clk_register_pll_out(const char *name,
 
 /* struct clk-periph - peripheral clock */
 struct tegra_clk_periph {
-	struct clk	hw;
+	struct clk_hw	hw;
 	struct clk	*gate;
 	struct clk	*mux;
 	struct clk	*div;
diff --git a/drivers/clk/vexpress/clk-sp810.c b/drivers/clk/vexpress/clk-sp810.c
index 8b5c193635..6eba0a2285 100644
--- a/drivers/clk/vexpress/clk-sp810.c
+++ b/drivers/clk/vexpress/clk-sp810.c
@@ -15,15 +15,15 @@
 struct clk_sp810;
 
 struct clk_sp810_timerclken {
-	struct clk hw;
+	struct clk_hw hw;
 	struct clk_sp810 *sp810;
 	int channel;
 };
 
 static inline struct clk_sp810_timerclken *
-to_clk_sp810_timerclken(struct clk *clk)
+to_clk_sp810_timerclken(struct clk_hw *hw)
 {
-	return container_of(clk, struct clk_sp810_timerclken, hw);
+	return container_of(hw, struct clk_sp810_timerclken, hw);
 }
 
 struct clk_sp810 {
@@ -32,12 +32,12 @@ struct clk_sp810 {
 	struct clk_sp810_timerclken timerclken[4];
 };
 
-static int clk_sp810_timerclken_get_parent(struct clk *hw)
+static int clk_sp810_timerclken_get_parent(struct clk_hw *hw)
 {
 	return 1;
 }
 
-static int clk_sp810_timerclken_set_parent(struct clk *hw, u8 index)
+static int clk_sp810_timerclken_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw);
 	struct clk_sp810 *sp810 = timerclken->sp810;
@@ -71,7 +71,7 @@ static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
 		    clkspec->args[0] >=	ARRAY_SIZE(sp810->timerclken)))
 		return NULL;
 
-	return &sp810->timerclken[clkspec->args[0]].hw;
+	return &sp810->timerclken[clkspec->args[0]].hw.clk;
 }
 
 static void clk_sp810_of_setup(struct device_node *node)
@@ -100,18 +100,18 @@ static void clk_sp810_of_setup(struct device_node *node)
 
 		sp810->timerclken[i].sp810 = sp810;
 		sp810->timerclken[i].channel = i;
-		sp810->timerclken[i].hw.name = strdup(name);
-		sp810->timerclken[i].hw.parent_names = parent_names;
-		sp810->timerclken[i].hw.num_parents = num;
-		sp810->timerclken[i].hw.ops = &clk_sp810_timerclken_ops;
+		sp810->timerclken[i].hw.clk.name = strdup(name);
+		sp810->timerclken[i].hw.clk.parent_names = parent_names;
+		sp810->timerclken[i].hw.clk.num_parents = num;
+		sp810->timerclken[i].hw.clk.ops = &clk_sp810_timerclken_ops;
+
+		bclk_register(&sp810->timerclken[i].hw.clk);
 
 		/*
 		 * Always set parent to 1MHz clock to match QEMU emulation
 		 * and satisfy requirements on real HW.
 		 */
 		clk_sp810_timerclken_set_parent(&sp810->timerclken[i].hw, 1);
-
-		bclk_register(&sp810->timerclken[i].hw);
 	}
 
 	of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index e4b2a855e5..e4ce102d6e 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -50,25 +50,25 @@ static struct clk *clks[clk_max];
 static struct clk_onecell_data clk_data;
 
 struct zynq_pll_clk {
-	struct clk	clk;
+	struct clk_hw	hw;
 	u32		pll_lock;
 	void __iomem	*pll_ctrl;
 };
 
-#define to_zynq_pll_clk(c)	container_of(c, struct zynq_pll_clk, clk)
+#define to_zynq_pll_clk(c)	container_of(c, struct zynq_pll_clk, hw)
 
 #define PLL_CTRL_FDIV(x)	(((x) >> 12) & 0x7F)
 
-static unsigned long zynq_pll_recalc_rate(struct clk *clk,
+static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
 					  unsigned long parent_rate)
 {
-	struct zynq_pll_clk *pll = to_zynq_pll_clk(clk);
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
 	return parent_rate * PLL_CTRL_FDIV(readl(pll->pll_ctrl));
 }
 
-static int zynq_pll_enable(struct clk *clk)
+static int zynq_pll_enable(struct clk_hw *hw)
 {
-	struct zynq_pll_clk *pll = to_zynq_pll_clk(clk);
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
 	u32 val;
 	int timeout = 10000;
 
@@ -87,9 +87,9 @@ static int zynq_pll_enable(struct clk *clk)
 	return 0;
 }
 
-static int zynq_pll_is_enabled(struct clk *clk)
+static int zynq_pll_is_enabled(struct clk_hw *hw)
 {
-	struct zynq_pll_clk *pll = to_zynq_pll_clk(clk);
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
 	u32 val = readl(pll->pll_ctrl);
 
 	return !(val & (PLL_CTRL_PWRDOWN | PLL_CTRL_RESET));
@@ -111,10 +111,10 @@ static inline struct clk *zynq_pll_clk(enum zynq_pll_type type,
 
 	pll = xzalloc(sizeof(*pll));
 	pll->pll_ctrl		= pll_ctrl;
-	pll->clk.ops		= &zynq_pll_clk_ops;
-	pll->clk.name		= name;
-	pll->clk.parent_names	= &pll_parent;
-	pll->clk.num_parents	= 1;
+	pll->hw.clk.ops = &zynq_pll_clk_ops;
+	pll->hw.clk.name = name;
+	pll->hw.clk.parent_names = &pll_parent;
+	pll->hw.clk.num_parents = 1;
 
 	switch(type) {
 	case ZYNQ_PLL_ARM:
@@ -128,17 +128,17 @@ static inline struct clk *zynq_pll_clk(enum zynq_pll_type type,
 		break;
 	}
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		free(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
 
 struct zynq_periph_clk {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*clk_ctrl;
 };
 
@@ -150,16 +150,16 @@ static const u8 periph_clk_parent_map[] = {
 #define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4])
 #define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8)
 
-static unsigned long zynq_periph_recalc_rate(struct clk *clk,
+static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
-	struct zynq_periph_clk *periph = to_zynq_periph_clk(clk);
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
 	return parent_rate / PERIPH_CLK_CTRL_DIV(readl(periph->clk_ctrl));
 }
 
-static int zynq_periph_get_parent(struct clk *clk)
+static int zynq_periph_get_parent(struct clk_hw *hw)
 {
-	struct zynq_periph_clk *periph = to_zynq_periph_clk(clk);
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
 	return PERIPH_CLK_CTRL_SRC(readl(periph->clk_ctrl));
 }
 
@@ -181,18 +181,18 @@ static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl)
 	periph = xzalloc(sizeof(*periph));
 
 	periph->clk_ctrl	= clk_ctrl;
-	periph->clk.name	= name;
-	periph->clk.ops		= &zynq_periph_clk_ops;
-	periph->clk.parent_names = peripheral_parents;
-	periph->clk.num_parents	= ARRAY_SIZE(peripheral_parents);
+	periph->hw.clk.name = name;
+	periph->hw.clk.ops = &zynq_periph_clk_ops;
+	periph->hw.clk.parent_names = peripheral_parents;
+	periph->hw.clk.num_parents = ARRAY_SIZE(peripheral_parents);
 
-	ret = bclk_register(&periph->clk);
+	ret = bclk_register(&periph->hw.clk);
 	if (ret) {
 		free(periph);
 		return ERR_PTR(ret);
 	}
 
-	return &periph->clk;
+	return &periph->hw.clk;
 }
 
 /* CPU Clock domain is modelled as a mux with 4 children subclks, whose
@@ -200,7 +200,7 @@ static struct clk *zynq_periph_clk(const char *name, void __iomem *clk_ctrl)
  */
 
 struct zynq_cpu_clk {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*clk_ctrl;
 };
 
@@ -212,16 +212,16 @@ static const u8 zynq_cpu_clk_parent_map[] = {
 #define CPU_CLK_SRCSEL(x)	(zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
 #define CPU_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
 
-static unsigned long zynq_cpu_clk_recalc_rate(struct clk *clk,
+static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw,
 					      unsigned long parent_rate)
 {
-	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk);
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
 	return parent_rate / CPU_CLK_CTRL_DIV(readl(cpuclk->clk_ctrl));
 }
 
-static int zynq_cpu_clk_get_parent(struct clk *clk)
+static int zynq_cpu_clk_get_parent(struct clk_hw *hw)
 {
-	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(clk);
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
 	return CPU_CLK_SRCSEL(readl(cpuclk->clk_ctrl));
 }
 
@@ -243,18 +243,18 @@ static struct clk *zynq_cpu_clk(const char *name, void __iomem *clk_ctrl)
 	cpu = xzalloc(sizeof(*cpu));
 
 	cpu->clk_ctrl		= clk_ctrl;
-	cpu->clk.ops		= &zynq_cpu_clk_ops;
-	cpu->clk.name		= name;
-	cpu->clk.parent_names	= cpu_parents;
-	cpu->clk.num_parents	= ARRAY_SIZE(cpu_parents);
+	cpu->hw.clk.ops = &zynq_cpu_clk_ops;
+	cpu->hw.clk.name = name;
+	cpu->hw.clk.parent_names = cpu_parents;
+	cpu->hw.clk.num_parents = ARRAY_SIZE(cpu_parents);
 
-	ret = bclk_register(&cpu->clk);
+	ret = bclk_register(&cpu->hw.clk);
 	if (ret) {
 		free(cpu);
 		return ERR_PTR(ret);
 	}
 
-	return &cpu->clk;
+	return &cpu->hw.clk;
 }
 
 enum zynq_cpu_subclk_which {
@@ -265,7 +265,7 @@ enum zynq_cpu_subclk_which {
 };
 
 struct zynq_cpu_subclk {
-	struct clk	clk;
+	struct clk_hw	hw;
 	void __iomem	*clk_ctrl;
 	void __iomem	*clk_621;
 	enum zynq_cpu_subclk_which which;
@@ -273,16 +273,16 @@ struct zynq_cpu_subclk {
 
 #define CLK_621_TRUE(x)		((x) & 1)
 
-#define to_zynq_cpu_subclk(c)	container_of(c, struct zynq_cpu_subclk, c);
+#define to_zynq_cpu_subclk(c)	container_of(c, struct zynq_cpu_subclk, hw);
 
-static unsigned long zynq_cpu_subclk_recalc_rate(struct clk *clk,
+static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw,
 						 unsigned long parent_rate)
 {
 	unsigned long uninitialized_var(rate);
 	struct zynq_cpu_subclk *subclk;
 	bool is_621;
 
-	subclk = to_zynq_cpu_subclk(clk);
+	subclk = to_zynq_cpu_subclk(hw);
 	is_621 = CLK_621_TRUE(readl(subclk->clk_621));
 
 	switch (subclk->which) {
@@ -303,12 +303,12 @@ static unsigned long zynq_cpu_subclk_recalc_rate(struct clk *clk,
 	return rate;
 }
 
-static int zynq_cpu_subclk_enable(struct clk *clk)
+static int zynq_cpu_subclk_enable(struct clk_hw *hw)
 {
 	struct zynq_cpu_subclk *subclk;
 	u32 tmp;
 
-	subclk = to_zynq_cpu_subclk(clk);
+	subclk = to_zynq_cpu_subclk(hw);
 
 	tmp = readl(subclk->clk_ctrl);
 	tmp |= 1 << (24 + subclk->which);
@@ -317,12 +317,12 @@ static int zynq_cpu_subclk_enable(struct clk *clk)
 	return 0;
 }
 
-static void zynq_cpu_subclk_disable(struct clk *clk)
+static void zynq_cpu_subclk_disable(struct clk_hw *hw)
 {
 	struct zynq_cpu_subclk *subclk;
 	u32 tmp;
 
-	subclk = to_zynq_cpu_subclk(clk);
+	subclk = to_zynq_cpu_subclk(hw);
 
 	tmp = readl(subclk->clk_ctrl);
 	tmp &= ~(1 << (24 + subclk->which));
@@ -349,19 +349,19 @@ static struct clk *zynq_cpu_subclk(const char *name,
 	subclk->clk_ctrl	= clk_ctrl;
 	subclk->clk_621		= clk_621;
 	subclk->which		= which;
-	subclk->clk.name	= name;
-	subclk->clk.ops		= &zynq_cpu_subclk_ops;
+	subclk->hw.clk.name = name;
+	subclk->hw.clk.ops = &zynq_cpu_subclk_ops;
 
-	subclk->clk.parent_names = &subclk_parent;
-	subclk->clk.num_parents	= 1;
+	subclk->hw.clk.parent_names = &subclk_parent;
+	subclk->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&subclk->clk);
+	ret = bclk_register(&subclk->hw.clk);
 	if (ret) {
 		free(subclk);
 		return ERR_PTR(ret);
 	}
 
-	return &subclk->clk;
+	return &subclk->hw.clk;
 }
 
 static int zynq_clock_probe(struct device_d *dev)
diff --git a/drivers/clk/zynqmp/clk-divider-zynqmp.c b/drivers/clk/zynqmp/clk-divider-zynqmp.c
index 09f63dd9b5..b96cab615b 100644
--- a/drivers/clk/zynqmp/clk-divider-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-divider-zynqmp.c
@@ -16,14 +16,14 @@
 #include "clk-zynqmp.h"
 
 struct zynqmp_clk_divider {
-	struct clk clk;
+	struct clk_hw hw;
 	unsigned int clk_id;
 	enum topology_type type;
 	const char *parent;
 	const struct zynqmp_eemi_ops *ops;
 };
-#define to_zynqmp_clk_divider(clk) \
-	container_of(clk, struct zynqmp_clk_divider, clk)
+#define to_zynqmp_clk_divider(_hw) \
+	container_of(_hw, struct zynqmp_clk_divider, hw)
 
 static int zynqmp_clk_divider_bestdiv(unsigned long rate,
 				      unsigned long *best_parent_rate)
@@ -31,10 +31,10 @@ static int zynqmp_clk_divider_bestdiv(unsigned long rate,
 	return DIV_ROUND_CLOSEST(*best_parent_rate, rate);
 }
 
-static unsigned long zynqmp_clk_divider_recalc_rate(struct clk *clk,
+static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
 						    unsigned long parent_rate)
 {
-	struct zynqmp_clk_divider *div = to_zynqmp_clk_divider(clk);
+	struct zynqmp_clk_divider *div = to_zynqmp_clk_divider(hw);
 	u32 value;
 
 	div->ops->clock_getdivider(div->clk_id, &value);
@@ -46,7 +46,7 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk *clk,
 	return DIV_ROUND_UP(parent_rate, value);
 }
 
-static long zynqmp_clk_divider_round_rate(struct clk *clk, unsigned long rate,
+static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 					  unsigned long *parent_rate)
 {
 	int bestdiv;
@@ -56,10 +56,10 @@ static long zynqmp_clk_divider_round_rate(struct clk *clk, unsigned long rate,
 	return *parent_rate / bestdiv;
 }
 
-static int zynqmp_clk_divider_set_rate(struct clk *clk, unsigned long rate,
+static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long parent_rate)
 {
-	struct zynqmp_clk_divider *div = to_zynqmp_clk_divider(clk);
+	struct zynqmp_clk_divider *div = to_zynqmp_clk_divider(hw);
 	u32 bestdiv;
 
 	bestdiv = zynqmp_clk_divider_bestdiv(rate, &parent_rate);
@@ -95,17 +95,17 @@ struct clk *zynqmp_clk_register_divider(const char *name,
 	div->ops = zynqmp_pm_get_eemi_ops();
 	div->parent = strdup(parents[0]);
 
-	div->clk.name = strdup(name);
-	div->clk.ops = &zynqmp_clk_divider_ops;
-	div->clk.flags = nodes->flag;
-	div->clk.parent_names = &div->parent;
-	div->clk.num_parents = 1;
+	div->hw.clk.name = strdup(name);
+	div->hw.clk.ops = &zynqmp_clk_divider_ops;
+	div->hw.clk.flags = nodes->flag;
+	div->hw.clk.parent_names = &div->parent;
+	div->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&div->clk);
+	ret = bclk_register(&div->hw.clk);
 	if (ret) {
 		kfree(div);
 		return ERR_PTR(ret);
 	}
 
-	return &div->clk;
+	return &div->hw.clk;
 }
diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index 9fbc15e966..a3b9ee21e5 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -16,31 +16,31 @@
 #include "clk-zynqmp.h"
 
 struct zynqmp_clk_gate {
-	struct clk clk;
+	struct clk_hw hw;
 	unsigned int clk_id;
 	const char *parent;
 	const struct zynqmp_eemi_ops *ops;
 };
 
-#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, clk)
+#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw)
 
-static int zynqmp_clk_gate_enable(struct clk *clk)
+static int zynqmp_clk_gate_enable(struct clk_hw *hw)
 {
-	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(clk);
+	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
 
 	return gate->ops->clock_enable(gate->clk_id);
 }
 
-static void zynqmp_clk_gate_disable(struct clk *clk)
+static void zynqmp_clk_gate_disable(struct clk_hw *hw)
 {
-	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(clk);
+	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
 
 	gate->ops->clock_disable(gate->clk_id);
 }
 
-static int zynqmp_clk_gate_is_enabled(struct clk *clk)
+static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
 {
-	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(clk);
+	struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
 	u32 state;
 	int ret;
 	const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
@@ -77,17 +77,17 @@ struct clk *zynqmp_clk_register_gate(const char *name,
 	gate->ops = zynqmp_pm_get_eemi_ops();
 	gate->parent = strdup(parents[0]);
 
-	gate->clk.name = strdup(name);
-	gate->clk.ops = &zynqmp_clk_gate_ops;
-	gate->clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
-	gate->clk.parent_names = &gate->parent;
-	gate->clk.num_parents = 1;
+	gate->hw.clk.name = strdup(name);
+	gate->hw.clk.ops = &zynqmp_clk_gate_ops;
+	gate->hw.clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
+	gate->hw.clk.parent_names = &gate->parent;
+	gate->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&gate->clk);
+	ret = bclk_register(&gate->hw.clk);
 	if (ret) {
 		kfree(gate);
 		return ERR_PTR(ret);
 	}
 
-	return &gate->clk;
+	return &gate->hw.clk;
 }
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index c3fdf11840..e7264375f5 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -18,17 +18,17 @@
 #define ZYNQMP_CLK_MUX_READ_ONLY		BIT(3)
 
 struct zynqmp_clk_mux {
-	struct clk clk;
+	struct clk_hw hw;
 	u32 clk_id;
 	const struct zynqmp_eemi_ops *ops;
 };
 
-#define to_zynqmp_clk_mux(clk) \
-	container_of(clk, struct zynqmp_clk_mux, clk)
+#define to_zynqmp_clk_mux(_hw) \
+	container_of(_hw, struct zynqmp_clk_mux, hw)
 
-static int zynqmp_clk_mux_get_parent(struct clk *clk)
+static int zynqmp_clk_mux_get_parent(struct clk_hw *hw)
 {
-	struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(clk);
+	struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw);
 	u32 value;
 
 	mux->ops->clock_getparent(mux->clk_id, &value);
@@ -36,9 +36,9 @@ static int zynqmp_clk_mux_get_parent(struct clk *clk)
 	return value;
 }
 
-static int zynqmp_clk_mux_set_parent(struct clk *clk, u8 index)
+static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(clk);
+	struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw);
 
 	return mux->ops->clock_setparent(mux->clk_id, index);
 }
@@ -82,21 +82,21 @@ struct clk *zynqmp_clk_register_mux(const char *name,
 	mux->clk_id = clk_id;
 	mux->ops = zynqmp_pm_get_eemi_ops();
 
-	mux->clk.name = strdup(name);
+	mux->hw.clk.name = strdup(name);
 	if (nodes->type_flag & ZYNQMP_CLK_MUX_READ_ONLY)
-		mux->clk.ops = &zynqmp_clk_mux_ro_ops;
+		mux->hw.clk.ops = &zynqmp_clk_mux_ro_ops;
 	else
-		mux->clk.ops = &zynqmp_clk_mux_ops;
-	mux->clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
-	mux->clk.parent_names = parent_names;
-	mux->clk.num_parents = num_parents;
+		mux->hw.clk.ops = &zynqmp_clk_mux_ops;
+	mux->hw.clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
+	mux->hw.clk.parent_names = parent_names;
+	mux->hw.clk.num_parents = num_parents;
 
-	ret = bclk_register(&mux->clk);
+	ret = bclk_register(&mux->hw.clk);
 	if (ret) {
 		kfree(parent_names);
 		kfree(mux);
 		return ERR_PTR(ret);
 	}
 
-	return &mux->clk;
+	return &mux->hw.clk;
 }
diff --git a/drivers/clk/zynqmp/clk-pll-zynqmp.c b/drivers/clk/zynqmp/clk-pll-zynqmp.c
index 6507222568..2e24d9d01c 100644
--- a/drivers/clk/zynqmp/clk-pll-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-pll-zynqmp.c
@@ -16,14 +16,14 @@
 #include "clk-zynqmp.h"
 
 struct zynqmp_pll {
-	struct clk clk;
+	struct clk_hw hw;
 	unsigned int clk_id;
 	const char *parent;
 	const struct zynqmp_eemi_ops *ops;
 };
 
-#define to_zynqmp_pll(clk) \
-	container_of(clk, struct zynqmp_pll, clk)
+#define to_zynqmp_pll(_hw) \
+	container_of(_hw, struct zynqmp_pll, hw)
 
 #define PLL_FBDIV_MIN		25
 #define PLL_FBDIV_MAX		125
@@ -53,10 +53,10 @@ static inline void zynqmp_pll_set_mode(struct zynqmp_pll *pll, enum pll_mode mod
 	pll->ops->ioctl(0, IOCTL_SET_PLL_FRAC_MODE, pll->clk_id, mode, NULL);
 }
 
-static long zynqmp_pll_round_rate(struct clk *clk, unsigned long rate,
+static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *prate)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 	u32 fbdiv;
 	long rate_div;
 
@@ -84,10 +84,10 @@ static long zynqmp_pll_round_rate(struct clk *clk, unsigned long rate,
 	return rate;
 }
 
-static unsigned long zynqmp_pll_recalc_rate(struct clk *clk,
+static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 	u32 clk_id = pll->clk_id;
 	u32 fbdiv, data;
 	unsigned long rate, frac;
@@ -109,10 +109,10 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk *clk,
 	return rate;
 }
 
-static int zynqmp_pll_set_rate(struct clk *clk, unsigned long rate,
+static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 	u32 clk_id = pll->clk_id;
 	u32 fbdiv;
 	long rate_div, frac, m, f;
@@ -138,9 +138,9 @@ static int zynqmp_pll_set_rate(struct clk *clk, unsigned long rate,
 	}
 }
 
-static int zynqmp_pll_is_enabled(struct clk *clk)
+static int zynqmp_pll_is_enabled(struct clk_hw *hw)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 	u32 is_enabled;
 	int ret;
 
@@ -151,21 +151,21 @@ static int zynqmp_pll_is_enabled(struct clk *clk)
 	return !!(is_enabled);
 }
 
-static int zynqmp_pll_enable(struct clk *clk)
+static int zynqmp_pll_enable(struct clk_hw *hw)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 
-	if (zynqmp_pll_is_enabled(clk))
+	if (zynqmp_pll_is_enabled(hw))
 		return 0;
 
 	return pll->ops->clock_enable(pll->clk_id);
 }
 
-static void zynqmp_pll_disable(struct clk *clk)
+static void zynqmp_pll_disable(struct clk_hw *hw)
 {
-	struct zynqmp_pll *pll = to_zynqmp_pll(clk);
+	struct zynqmp_pll *pll = to_zynqmp_pll(hw);
 
-	if (!zynqmp_pll_is_enabled(clk))
+	if (!zynqmp_pll_is_enabled(hw))
 		return;
 
 	pll->ops->clock_disable(pll->clk_id);
@@ -197,17 +197,17 @@ struct clk *zynqmp_clk_register_pll(const char *name,
 	pll->ops = zynqmp_pm_get_eemi_ops();
 	pll->parent = strdup(parents[0]);
 
-	pll->clk.name = strdup(name);
-	pll->clk.ops = &zynqmp_pll_ops;
-	pll->clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
-	pll->clk.parent_names = &pll->parent;
-	pll->clk.num_parents = 1;
+	pll->hw.clk.name = strdup(name);
+	pll->hw.clk.ops = &zynqmp_pll_ops;
+	pll->hw.clk.flags = nodes->flag | CLK_SET_RATE_PARENT;
+	pll->hw.clk.parent_names = &pll->parent;
+	pll->hw.clk.num_parents = 1;
 
-	ret = bclk_register(&pll->clk);
+	ret = bclk_register(&pll->hw.clk);
 	if (ret) {
 		kfree(pll);
 		return ERR_PTR(ret);
 	}
 
-	return &pll->clk;
+	return &pll->hw.clk;
 }
diff --git a/drivers/video/imx-ipu-v3/ipu-di.c b/drivers/video/imx-ipu-v3/ipu-di.c
index 0f382f8c42..85dde1882e 100644
--- a/drivers/video/imx-ipu-v3/ipu-di.c
+++ b/drivers/video/imx-ipu-v3/ipu-di.c
@@ -167,9 +167,10 @@ static int ipu_di_clk_calc_div(unsigned long inrate, unsigned long outrate)
 	return div;
 }
 
-static unsigned long clk_di_recalc_rate(struct clk *clk,
+static unsigned long clk_di_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
 	unsigned long outrate;
 	u32 div = ipu_di_read(di, DI_BS_CLKGEN0);
@@ -182,9 +183,10 @@ static unsigned long clk_di_recalc_rate(struct clk *clk,
 	return outrate;
 }
 
-static long clk_di_round_rate(struct clk *clk, unsigned long rate,
+static long clk_di_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
 	unsigned long outrate;
 	int div;
@@ -206,9 +208,10 @@ static long clk_di_round_rate(struct clk *clk, unsigned long rate,
 	return outrate;
 }
 
-static int clk_di_set_rate(struct clk *clk, unsigned long rate,
+static int clk_di_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
 	int div;
 	u32 clkgen0;
@@ -224,8 +227,9 @@ static int clk_di_set_rate(struct clk *clk, unsigned long rate,
 	return 0;
 }
 
-static int clk_di_get_parent(struct clk *clk)
+static int clk_di_get_parent(struct clk_hw *hw)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
 	u32 val;
 
@@ -234,8 +238,9 @@ static int clk_di_get_parent(struct clk *clk)
 	return val & DI_GEN_DI_CLK_EXT ? 1 : 0;
 }
 
-static int clk_di_set_parent(struct clk *clk, u8 index)
+static int clk_di_set_parent(struct clk_hw *hw, u8 index)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct ipu_di *di = container_of(clk, struct ipu_di, clk_di_pixel);
 	u32 val;
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 71c5e23e91..66ac6a9f14 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -23,6 +23,7 @@ struct device_d;
  * struct clk - an machine class defined object / cookie.
  */
 struct clk;
+struct clk_hw;
 
 /**
  * struct clk_bulk_data - Data used for bulk clk operations.
@@ -163,6 +164,7 @@ void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks);
  * @clk: clock source
  */
 unsigned long clk_get_rate(struct clk *clk);
+unsigned long clk_hw_get_rate(struct clk_hw *hw);
 
 /**
  * clk_bulk_put	- "free" the clock source
@@ -203,7 +205,7 @@ void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks);
  * Returns rounded clock rate in Hz, or negative errno.
  */
 long clk_round_rate(struct clk *clk, unsigned long rate);
-
+long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate);
 /**
  * clk_set_rate - set the clock rate for a clock source
  * @clk: clock source
@@ -212,6 +214,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate);
  * Returns success (0) or negative errno.
  */
 int clk_set_rate(struct clk *clk, unsigned long rate);
+int clk_hw_set_rate(struct clk_hw *hw, unsigned long rate);
 
 /**
  * clk_set_parent - set the parent clock source for this clock
@@ -221,6 +224,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate);
  * Returns success (0) or negative errno.
  */
 int clk_set_parent(struct clk *clk, struct clk *parent);
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *hwp);
 
 /**
  * clk_get_parent - get the parent clock source for this clock
@@ -230,6 +234,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent);
  * valid IS_ERR() condition containing errno.
  */
 struct clk *clk_get_parent(struct clk *clk);
+struct clk_hw *clk_hw_get_parent(struct clk_hw *hw);
 
 /**
  * clk_get_sys - get a clock based upon the device name
@@ -336,20 +341,38 @@ static inline void clk_put(struct clk *clk)
 #define CLK_GATE_HIWORD_MASK	(1 << 1)
 
 struct clk_ops {
-	int 		(*init)(struct clk *clk);
-	int		(*enable)(struct clk *clk);
-	void		(*disable)(struct clk *clk);
-	int		(*is_enabled)(struct clk *clk);
-	unsigned long	(*recalc_rate)(struct clk *clk,
+	int 		(*init)(struct clk_hw *hw);
+	int		(*enable)(struct clk_hw *hw);
+	void		(*disable)(struct clk_hw *hw);
+	int		(*is_enabled)(struct clk_hw *hw);
+	unsigned long	(*recalc_rate)(struct clk_hw *hw,
 					unsigned long parent_rate);
-	long		(*round_rate)(struct clk *clk, unsigned long,
+	long		(*round_rate)(struct clk_hw *hw, unsigned long,
 					unsigned long *);
-	int		(*set_parent)(struct clk *clk, u8 index);
-	int		(*get_parent)(struct clk *clk);
-	int		(*set_rate)(struct clk *clk, unsigned long,
+	int		(*set_parent)(struct clk_hw *hw, u8 index);
+	int		(*get_parent)(struct clk_hw *hw);
+	int		(*set_rate)(struct clk_hw *hw, unsigned long,
 				    unsigned long);
 };
 
+/**
+ * struct clk_init_data - holds init data that's common to all clocks and is
+ * shared between the clock provider and the common clock framework.
+ *
+ * @name: clock name
+ * @ops: operations this clock supports
+ * @parent_names: array of string names for all possible parents
+ * @num_parents: number of possible parents
+ * @flags: framework-level hints and quirks
+ */
+struct clk_init_data {
+	const char		*name;
+	const struct clk_ops	*ops;
+	const char		* const *parent_names;
+	unsigned int		num_parents;
+	unsigned long		flags;
+};
+
 struct clk {
 	const struct clk_ops *ops;
 	int enable_count;
@@ -362,6 +385,32 @@ struct clk {
 	unsigned long flags;
 };
 
+/**
+ * struct clk_hw - handle for traversing from a struct clk to its corresponding
+ * hardware-specific structure.  struct clk_hw should be declared within struct
+ * clk_foo and then referenced by the struct clk instance that uses struct
+ * clk_foo's clk_ops
+ *
+ * @clk: pointer to the per-user struct clk instance that can be used to call
+ * into the clk API
+ *
+ * @init: pointer to struct clk_init_data that contains the init data shared
+ * with the common clock framework.
+ */
+struct clk_hw {
+	struct clk clk;
+};
+
+static inline struct clk *clk_hw_to_clk(struct clk_hw *hw)
+{
+	return &hw->clk;
+}
+
+static inline struct clk_hw *clk_to_clk_hw(struct clk *clk)
+{
+	return container_of(clk, struct clk_hw, clk);
+}
+
 struct clk_div_table {
 	unsigned int	val;
 	unsigned int	div;
@@ -377,7 +426,7 @@ static inline struct clk *clk_fixed(const char *name, int rate)
 }
 
 struct clk_divider {
-	struct clk clk;
+	struct clk_hw hw;
 	u8 shift;
 	u8 width;
 	void __iomem *reg;
@@ -389,6 +438,8 @@ struct clk_divider {
 	int table_size;
 };
 
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
 #define clk_div_mask(width)	((1 << (width)) - 1)
 
 #define CLK_DIVIDER_POWER_OF_TWO	(1 << 1)
@@ -441,14 +492,14 @@ struct clk *clk_fractional_divider(
 void clk_fractional_divider_free(struct clk *clk_fd);
 
 struct clk_mux {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	int shift;
 	int width;
 	unsigned flags;
 };
 
-#define to_clk_mux(_clk) container_of(_clk, struct clk_mux, clk)
+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
 
 extern struct clk_ops clk_mux_ops;
 
@@ -462,16 +513,16 @@ struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
 		    u8 num_parents, unsigned mux_flags);
 
 struct clk_gate {
-	struct clk clk;
+	struct clk_hw hw;
 	void __iomem *reg;
 	int shift;
 	const char *parent;
 	unsigned flags;
 };
 
-int clk_gate_is_enabled(struct clk *clk);
+int clk_gate_is_enabled(struct clk_hw *hw);
 
-#define to_clk_gate(_clk) container_of(_clk, struct clk_gate, clk)
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
 
 extern struct clk_ops clk_gate_ops;
 
@@ -487,11 +538,12 @@ struct clk *clk_gate_shared(const char *name, const char *parent, const char *sh
 			    unsigned flags);
 
 int clk_is_enabled(struct clk *clk);
+int clk_hw_is_enabled(struct clk_hw *hw);
 
-int clk_is_enabled_always(struct clk *clk);
-long clk_parent_round_rate(struct clk *clk, unsigned long rate,
+int clk_is_enabled_always(struct clk_hw *hw);
+long clk_parent_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate);
-int clk_parent_set_rate(struct clk *clk, unsigned long rate,
+int clk_parent_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate);
 
 int bclk_register(struct clk *clk);
@@ -507,6 +559,12 @@ struct clk *clk_register_composite(const char *name,
 			struct clk *rate_clk,
 			struct clk *gate_clk,
 			unsigned long flags);
+
+static inline const char *clk_hw_get_name(struct clk_hw *hw)
+{
+	return hw->clk.name;
+}
+
 #endif
 
 struct device_node;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 05/24] clk: introduce clk_register()
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (3 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 04/24] clk: introduce struct clk_hw Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 06/24] clk: divider: Make clk_divider_ops const Sascha Hauer
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List; +Cc: Ahmad Fatoum

This introduces a clk_register() with the same semantics as in Linux.
This also adds a struct clk_init_data. With this it becomes easier to
port over new clock drivers from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/clk/clk.c   | 37 +++++++++++++++++++++++++++++++++++++
 include/linux/clk.h |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 73682126bf..74e2f5d783 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -345,6 +345,43 @@ out:
 	return ret;
 }
 
+struct clk *clk_register(struct device_d *dev, struct clk_hw *hw)
+{
+	struct clk *clk;
+	const struct clk_init_data *init = hw->init;
+	char **parent_names;
+	int i, ret;
+
+	if (!hw->init)
+		return ERR_PTR(-EINVAL);
+
+	clk = clk_hw_to_clk(hw);
+
+	memset(clk, 0, sizeof(*clk));
+
+	clk->name = xstrdup(init->name);
+	clk->ops = init->ops;
+	clk->num_parents = init->num_parents;
+	parent_names = xzalloc(init->num_parents * sizeof(char *));
+
+	for (i = 0; i < init->num_parents; i++)
+		parent_names[i] = xstrdup(init->parent_names[i]);
+
+	clk->parent_names = (const char *const*)parent_names;
+
+	clk->flags = init->flags;
+
+	ret = bclk_register(clk);
+	if (ret) {
+		for (i = 0; i < init->num_parents; i++)
+			free(parent_names[i]);
+		free(parent_names);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
 int clk_is_enabled(struct clk *clk)
 {
 	int enabled;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 66ac6a9f14..654845023a 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -399,6 +399,7 @@ struct clk {
  */
 struct clk_hw {
 	struct clk clk;
+	const struct clk_init_data *init;
 };
 
 static inline struct clk *clk_hw_to_clk(struct clk_hw *hw)
@@ -547,6 +548,7 @@ int clk_parent_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate);
 
 int bclk_register(struct clk *clk);
+struct clk *clk_register(struct device_d *dev, struct clk_hw *hw);
 
 struct clk *clk_lookup(const char *name);
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 06/24] clk: divider: Make clk_divider_ops const
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (4 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 05/24] clk: introduce clk_register() Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 07/24] clk: divider: Add ro ops Sascha Hauer
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

clk_divider_ops shouldn't be changed, so make it const.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-divider.c | 2 +-
 include/linux/clk.h       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index edbba941b7..446b35e1ed 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -296,7 +296,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
-struct clk_ops clk_divider_ops = {
+const struct clk_ops clk_divider_ops = {
 	.set_rate = clk_divider_set_rate,
 	.recalc_rate = clk_divider_recalc_rate,
 	.round_rate = clk_divider_round_rate,
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 654845023a..b8674973fa 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -450,7 +450,7 @@ struct clk_divider {
 #define CLK_MUX_HIWORD_MASK		(1 << 2)
 #define CLK_MUX_READ_ONLY		(1 << 3) /* mux can't be changed */
 
-extern struct clk_ops clk_divider_ops;
+extern const struct clk_ops clk_divider_ops;
 
 unsigned long divider_recalc_rate(struct clk *clk, unsigned long parent_rate,
 		unsigned int val,
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 07/24] clk: divider: Add ro ops
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (5 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 06/24] clk: divider: Make clk_divider_ops const Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 08/24] clk: divider: Make clk_mux_ops const Sascha Hauer
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

The Linux version of the clk divider exports a clk_divider_ro_ops. Do
the same for barebox.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-divider.c | 4 ++++
 include/linux/clk.h       | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 446b35e1ed..447c43dc93 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -302,6 +302,10 @@ const struct clk_ops clk_divider_ops = {
 	.round_rate = clk_divider_round_rate,
 };
 
+const struct clk_ops clk_divider_ro_ops = {
+	.recalc_rate = clk_divider_recalc_rate,
+};
+
 struct clk *clk_divider_alloc(const char *name, const char *parent,
 			      unsigned clk_flags, void __iomem *reg, u8 shift,
 			      u8 width, unsigned div_flags)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index b8674973fa..e1db903d74 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -451,6 +451,7 @@ struct clk_divider {
 #define CLK_MUX_READ_ONLY		(1 << 3) /* mux can't be changed */
 
 extern const struct clk_ops clk_divider_ops;
+extern const struct clk_ops clk_divider_ro_ops;
 
 unsigned long divider_recalc_rate(struct clk *clk, unsigned long parent_rate,
 		unsigned int val,
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 08/24] clk: divider: Make clk_mux_ops const
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (6 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 07/24] clk: divider: Add ro ops Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 09/24] clk: mux: Add ro ops Sascha Hauer
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

clk_mux_ops shouldn't be changed, so make it const.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c | 2 +-
 include/linux/clk.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 981f3aa853..bd5b50ad18 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -41,7 +41,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 idx)
 	return 0;
 }
 
-struct clk_ops clk_mux_ops = {
+const struct clk_ops clk_mux_ops = {
 	.set_rate = clk_parent_set_rate,
 	.round_rate = clk_parent_round_rate,
 	.get_parent = clk_mux_get_parent,
diff --git a/include/linux/clk.h b/include/linux/clk.h
index e1db903d74..ede2b676fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -503,7 +503,7 @@ struct clk_mux {
 
 #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
 
-extern struct clk_ops clk_mux_ops;
+extern const struct clk_ops clk_mux_ops;
 
 struct clk *clk_mux_alloc(const char *name, unsigned clk_flags,
 			  void __iomem *reg, u8 shift, u8 width,
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 09/24] clk: mux: Add ro ops
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (7 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 08/24] clk: divider: Make clk_mux_ops const Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 10/24] clk: move fixed_factor to include/linux/clk.h Sascha Hauer
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

The Linux version of the clk muxr exports a clk_mux_ro_ops. Do
the same for barebox.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c | 4 ++++
 include/linux/clk.h   | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index bd5b50ad18..464593b619 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -48,6 +48,10 @@ const struct clk_ops clk_mux_ops = {
 	.set_parent = clk_mux_set_parent,
 };
 
+const struct clk_ops clk_mux_ro_ops = {
+	.get_parent = clk_mux_get_parent,
+};
+
 struct clk *clk_mux_alloc(const char *name, unsigned clk_flags, void __iomem *reg,
 		u8 shift, u8 width, const char * const *parents, u8 num_parents,
 		unsigned mux_flags)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index ede2b676fe..edf64cd9aa 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -504,6 +504,7 @@ struct clk_mux {
 #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
 
 extern const struct clk_ops clk_mux_ops;
+extern const struct clk_ops clk_mux_ro_ops;
 
 struct clk *clk_mux_alloc(const char *name, unsigned clk_flags,
 			  void __iomem *reg, u8 shift, u8 width,
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 10/24] clk: move fixed_factor to include/linux/clk.h
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (8 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 09/24] clk: mux: Add ro ops Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 11/24] Add rational_best_approximation() Sascha Hauer
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

In Linux struct clk_fixed_factor is known to clk implementors. Do the
same in barebox.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-fixed-factor.c | 14 +-------------
 include/linux/clk.h            | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 506c4aea74..4f1a07c629 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -10,18 +10,6 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-struct clk_fixed_factor {
-	struct clk_hw hw;
-	int mult;
-	int div;
-	const char *parent;
-};
-
-static inline struct clk_fixed_factor *to_clk_fixed_factor(struct clk_hw *hw)
-{
-	return container_of(hw, struct clk_fixed_factor, hw);
-}
-
 static unsigned long clk_fixed_factor_recalc_rate(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
@@ -59,7 +47,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
-static struct clk_ops clk_fixed_factor_ops = {
+struct clk_ops clk_fixed_factor_ops = {
 	.set_rate = clk_factor_set_rate,
 	.round_rate = clk_factor_round_rate,
 	.recalc_rate = clk_fixed_factor_recalc_rate,
diff --git a/include/linux/clk.h b/include/linux/clk.h
index edf64cd9aa..7140aa9509 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -480,6 +480,21 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 			      unsigned clk_flags, void __iomem *reg, u8 shift,
 			      u8 width, const struct clk_div_table *table,
 			      unsigned div_flags);
+
+struct clk_fixed_factor {
+	struct clk_hw hw;
+	int mult;
+	int div;
+	const char *parent;
+};
+
+static inline struct clk_fixed_factor *to_clk_fixed_factor(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_fixed_factor, hw);
+}
+
+extern struct clk_ops clk_fixed_factor_ops;
+
 struct clk *clk_fixed_factor(const char *name,
 		const char *parent, unsigned int mult, unsigned int div,
 		unsigned flags);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 11/24] Add rational_best_approximation()
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (9 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 10/24] clk: move fixed_factor to include/linux/clk.h Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02 18:25   ` Trent Piepho
  2021-06-02  9:54 ` [PATCH 12/24] clk: Update fractional divider from Linux Sascha Hauer
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List; +Cc: Ahmad Fatoum

Import rational_best_approximation() from Linux. This is used by an
upcoming update of the clk_fractional_divider code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/linux/rational.h |  20 ++++++++
 lib/math/Makefile        |   1 +
 lib/math/rational.c      | 100 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 include/linux/rational.h
 create mode 100644 lib/math/rational.c

diff --git a/include/linux/rational.h b/include/linux/rational.h
new file mode 100644
index 0000000000..33f5f5fc3e
--- /dev/null
+++ b/include/linux/rational.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * rational fractions
+ *
+ * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <oskar@scara.com>
+ *
+ * helper functions when coping with rational numbers,
+ * e.g. when calculating optimum numerator/denominator pairs for
+ * pll configuration taking into account restricted register size
+ */
+
+#ifndef _LINUX_RATIONAL_H
+#define _LINUX_RATIONAL_H
+
+void rational_best_approximation(
+	unsigned long given_numerator, unsigned long given_denominator,
+	unsigned long max_numerator, unsigned long max_denominator,
+	unsigned long *best_numerator, unsigned long *best_denominator);
+
+#endif /* _LINUX_RATIONAL_H */
diff --git a/lib/math/Makefile b/lib/math/Makefile
index c2c892dd55..756d7dd90d 100644
--- a/lib/math/Makefile
+++ b/lib/math/Makefile
@@ -1,2 +1,3 @@
 obj-y += div64.o
 pbl-y += div64.o
+obj-y += rational.o
diff --git a/lib/math/rational.c b/lib/math/rational.c
new file mode 100644
index 0000000000..e5367e6a8a
--- /dev/null
+++ b/lib/math/rational.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * rational fractions
+ *
+ * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <oskar@scara.com>
+ * Copyright (C) 2019 Trent Piepho <tpiepho@gmail.com>
+ *
+ * helper functions when coping with rational numbers
+ */
+
+#include <linux/rational.h>
+#include <linux/compiler.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+
+/*
+ * calculate best rational approximation for a given fraction
+ * taking into account restricted register size, e.g. to find
+ * appropriate values for a pll with 5 bit denominator and
+ * 8 bit numerator register fields, trying to set up with a
+ * frequency ratio of 3.1415, one would say:
+ *
+ * rational_best_approximation(31415, 10000,
+ *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * https://en.wikipedia.org/wiki/Continued_fraction
+ */
+
+void rational_best_approximation(
+	unsigned long given_numerator, unsigned long given_denominator,
+	unsigned long max_numerator, unsigned long max_denominator,
+	unsigned long *best_numerator, unsigned long *best_denominator)
+{
+	/* n/d is the starting rational, which is continually
+	 * decreased each iteration using the Euclidean algorithm.
+	 *
+	 * dp is the value of d from the prior iteration.
+	 *
+	 * n2/d2, n1/d1, and n0/d0 are our successively more accurate
+	 * approximations of the rational.  They are, respectively,
+	 * the current, previous, and two prior iterations of it.
+	 *
+	 * a is current term of the continued fraction.
+	 */
+	unsigned long n, d, n0, d0, n1, d1, n2, d2;
+	n = given_numerator;
+	d = given_denominator;
+	n0 = d1 = 0;
+	n1 = d0 = 1;
+
+	for (;;) {
+		unsigned long dp, a;
+
+		if (d == 0)
+			break;
+		/* Find next term in continued fraction, 'a', via
+		 * Euclidean algorithm.
+		 */
+		dp = d;
+		a = n / d;
+		d = n % d;
+		n = dp;
+
+		/* Calculate the current rational approximation (aka
+		 * convergent), n2/d2, using the term just found and
+		 * the two prior approximations.
+		 */
+		n2 = n0 + a * n1;
+		d2 = d0 + a * d1;
+
+		/* If the current convergent exceeds the maxes, then
+		 * return either the previous convergent or the
+		 * largest semi-convergent, the final term of which is
+		 * found below as 't'.
+		 */
+		if ((n2 > max_numerator) || (d2 > max_denominator)) {
+			unsigned long t = min((max_numerator - n0) / n1,
+					      (max_denominator - d0) / d1);
+
+			/* This tests if the semi-convergent is closer
+			 * than the previous convergent.
+			 */
+			if (2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
+				n1 = n0 + t * n1;
+				d1 = d0 + t * d1;
+			}
+			break;
+		}
+		n0 = n1;
+		n1 = n2;
+		d0 = d1;
+		d1 = d2;
+	}
+	*best_numerator = n1;
+	*best_denominator = d1;
+}
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 12/24] clk: Update fractional divider from Linux
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (10 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 11/24] Add rational_best_approximation() Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 13/24] clk: Add lock to different clock types Sascha Hauer
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

This updates the fractional divider implementation from Linux-5.12.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-fractional-divider.c | 111 +++++++++++++++++++--------
 include/linux/clk.h                  |  44 +++++++++++
 2 files changed, 122 insertions(+), 33 deletions(-)

diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 65abf84b40..3d96360025 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -1,86 +1,129 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2014 Intel Corporation
  *
  * Adjustable fractional divider clock implementation.
  * Output rate = (m / n) * parent_rate.
+ * Uses rational best approximation algorithm.
  */
 
 #include <common.h>
 #include <io.h>
 #include <malloc.h>
 #include <linux/clk.h>
+#include <linux/spinlock.h>
 #include <linux/err.h>
 #include <linux/gcd.h>
 #include <linux/math64.h>
+#include <linux/rational.h>
 #include <linux/barebox-wrapper.h>
 
-#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
+static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
+{
+	if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+		return ioread32be(fd->reg);
 
-struct clk_fractional_divider {
-	struct clk_hw	hw;
-	void __iomem	*reg;
-	u8		mshift;
-	u32		mmask;
-	u8		nshift;
-	u32		nmask;
-	u8		flags;
-};
+	return readl(fd->reg);
+}
+
+static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val)
+{
+	if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+		iowrite32be(val, fd->reg);
+	else
+		writel(val, fd->reg);
+}
 
 static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 					unsigned long parent_rate)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
-	u32 val, m, n;
+	unsigned long m, n;
+	u32 val;
 	u64 ret;
 
-	val = readl(fd->reg);
+	val = clk_fd_readl(fd);
 
 	m = (val & fd->mmask) >> fd->mshift;
 	n = (val & fd->nmask) >> fd->nshift;
 
+	if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+		m++;
+		n++;
+	}
+
+	if (!n || !m)
+		return parent_rate;
+
 	ret = (u64)parent_rate * m;
 	do_div(ret, n);
 
 	return ret;
 }
 
+static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate,
+					 unsigned long *parent_rate,
+					 unsigned long *m, unsigned long *n)
+{
+	struct clk_fractional_divider *fd = to_clk_fd(hw);
+	unsigned long scale;
+
+	/*
+	 * Get rate closer to *parent_rate to guarantee there is no overflow
+	 * for m and n. In the result it will be the nearest rate left shifted
+	 * by (scale - fd->nwidth) bits.
+	 */
+	scale = fls_long(*parent_rate / rate - 1);
+	if (scale > fd->nwidth)
+		rate <<= scale - fd->nwidth;
+
+	rational_best_approximation(rate, *parent_rate,
+			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+			m, n);
+}
+
 static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
-			      unsigned long *prate)
+			      unsigned long *parent_rate)
 {
+	struct clk *clk = clk_hw_to_clk(hw);
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
-	unsigned maxn = (fd->nmask >> fd->nshift) + 1;
-	unsigned div;
+	unsigned long m, n;
+	u64 ret;
 
-	if (!rate || rate >= *prate)
-		return *prate;
+	if (!rate || (!(clk->flags & CLK_SET_RATE_PARENT) && rate >= *parent_rate))
+		return *parent_rate;
 
-	div = gcd(*prate, rate);
+	if (fd->approximation)
+		fd->approximation(hw, rate, parent_rate, &m, &n);
+	else
+		clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
 
-	while ((*prate / div) > maxn) {
-		div <<= 1;
-		rate <<= 1;
-	}
+	ret = (u64)*parent_rate * m;
+	do_div(ret, n);
 
-	return rate;
+	return ret;
 }
 
 static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
 			   unsigned long parent_rate)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
-	unsigned long div;
-	unsigned n, m;
+	unsigned long m, n;
 	u32 val;
 
-	div = gcd(parent_rate, rate);
-	m = rate / div;
-	n = parent_rate / div;
+	rational_best_approximation(rate, parent_rate,
+			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+			&m, &n);
+
+	if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+		m--;
+		n--;
+	}
 
-	val = readl(fd->reg);
+	val = clk_fd_readl(fd);
 	val &= ~(fd->mmask | fd->nmask);
 	val |= (m << fd->mshift) | (n << fd->nshift);
-	writel(val, fd->reg);
+	clk_fd_writel(fd, val);
 
 	return 0;
 }
@@ -103,9 +146,11 @@ struct clk *clk_fractional_divider_alloc(
 
 	fd->reg = reg;
 	fd->mshift = mshift;
-	fd->mmask = (BIT(mwidth) - 1) << mshift;
+	fd->mwidth = mwidth;
+	fd->mmask = GENMASK(mwidth - 1, 0) << mshift;
 	fd->nshift = nshift;
-	fd->nmask = (BIT(nwidth) - 1) << nshift;
+	fd->nwidth = nwidth;
+	fd->nmask = GENMASK(nwidth - 1, 0) << nshift;
 	fd->flags = clk_divider_flags;
 	fd->hw.clk.name = name;
 	fd->hw.clk.ops = &clk_fractional_divider_ops;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7140aa9509..39288f5025 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -498,6 +498,46 @@ extern struct clk_ops clk_fixed_factor_ops;
 struct clk *clk_fixed_factor(const char *name,
 		const char *parent, unsigned int mult, unsigned int div,
 		unsigned flags);
+
+/**
+ * struct clk_fractional_divider - adjustable fractional divider clock
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	register containing the divider
+ * @mshift:	shift to the numerator bit field
+ * @mwidth:	width of the numerator bit field
+ * @nshift:	shift to the denominator bit field
+ * @nwidth:	width of the denominator bit field
+ *
+ * Clock with adjustable fractional divider affecting its output frequency.
+ *
+ * Flags:
+ * CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator
+ *      is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
+ *      is set then the numerator and denominator are both the value read
+ *      plus one.
+ * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are
+ *      used for the divider register.  Setting this flag makes the register
+ *      accesses big endian.
+ */
+struct clk_fractional_divider {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		mshift;
+	u8		mwidth;
+	u32		mmask;
+	u8		nshift;
+	u8		nwidth;
+	u32		nmask;
+	u8		flags;
+	void		(*approximation)(struct clk_hw *hw,
+				unsigned long rate, unsigned long *parent_rate,
+				unsigned long *m, unsigned long *n);
+};
+
+#define CLK_FRAC_DIVIDER_ZERO_BASED		BIT(0)
+#define CLK_FRAC_DIVIDER_BIG_ENDIAN		BIT(1)
+
 struct clk *clk_fractional_divider_alloc(
 		const char *name, const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
@@ -508,6 +548,10 @@ struct clk *clk_fractional_divider(
 		u8 clk_divider_flags);
 void clk_fractional_divider_free(struct clk *clk_fd);
 
+#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
+
+extern const struct clk_ops clk_fractional_divider_ops;
+
 struct clk_mux {
 	struct clk_hw hw;
 	void __iomem *reg;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 13/24] clk: Add lock to different clock types
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (11 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 12/24] clk: Update fractional divider from Linux Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 14/24] clk: Add Linux functions to register a divider Sascha Hauer
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

The different clock types in Linux have a spinlock_t *lock field. Add
the same in barebox to ease code porting from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/clk.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 39288f5025..9d09738dda 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -11,6 +11,7 @@
 #define __LINUX_CLK_H
 
 #include <linux/err.h>
+#include <linux/spinlock.h>
 #include <linux/stringify.h>
 
 struct device_d;
@@ -437,6 +438,7 @@ struct clk_divider {
 	const struct clk_div_table *table;
 	int max_div_index;
 	int table_size;
+	spinlock_t *lock;
 };
 
 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
@@ -533,6 +535,7 @@ struct clk_fractional_divider {
 	void		(*approximation)(struct clk_hw *hw,
 				unsigned long rate, unsigned long *parent_rate,
 				unsigned long *m, unsigned long *n);
+	spinlock_t *lock;
 };
 
 #define CLK_FRAC_DIVIDER_ZERO_BASED		BIT(0)
@@ -558,6 +561,7 @@ struct clk_mux {
 	int shift;
 	int width;
 	unsigned flags;
+	spinlock_t *lock;
 };
 
 #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
@@ -580,6 +584,7 @@ struct clk_gate {
 	int shift;
 	const char *parent;
 	unsigned flags;
+	spinlock_t *lock;
 };
 
 int clk_gate_is_enabled(struct clk_hw *hw);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 14/24] clk: Add Linux functions to register a divider
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (12 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 13/24] clk: Add lock to different clock types Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 15/24] clk: Add Linux functions to register a fixed factor clock Sascha Hauer
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

Linux has clk_register_divider() and clk_register_divider_table(). Add
the same functions with the same prototypes for barebox to ease code
porting from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-divider.c | 19 +++++++++++++++++++
 include/linux/clk.h       |  9 +++++++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 447c43dc93..856b8a0648 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -409,3 +409,22 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 
 	return &div->hw.clk;
 }
+
+struct clk *clk_register_divider_table(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, const struct clk_div_table *table,
+		spinlock_t *lock)
+{
+	return clk_divider_table(name, parent_name, flags, reg, shift, width,
+				 table, clk_divider_flags);
+}
+
+struct clk *clk_register_divider(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, spinlock_t *lock)
+{
+	return clk_divider(name, parent_name, flags, reg, shift, width,
+			   clk_divider_flags);
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 9d09738dda..ba98c5307e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -475,6 +475,10 @@ void clk_divider_free(struct clk *clk_divider);
 struct clk *clk_divider(const char *name, const char *parent,
 			unsigned clk_flags, void __iomem *reg, u8 shift,
 			u8 width, unsigned div_flags);
+struct clk *clk_register_divider(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, spinlock_t *lock);
 struct clk *clk_divider_one_based(const char *name, const char *parent,
 				  unsigned clk_flags, void __iomem *reg,
 				  u8 shift, u8 width, unsigned div_flags);
@@ -482,6 +486,11 @@ struct clk *clk_divider_table(const char *name, const char *parent,
 			      unsigned clk_flags, void __iomem *reg, u8 shift,
 			      u8 width, const struct clk_div_table *table,
 			      unsigned div_flags);
+struct clk *clk_register_divider_table(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, const struct clk_div_table *table,
+		spinlock_t *lock);
 
 struct clk_fixed_factor {
 	struct clk_hw hw;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 15/24] clk: Add Linux functions to register a fixed factor clock
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (13 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 14/24] clk: Add Linux functions to register a divider Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:54 ` [PATCH 16/24] clk: Add Linux functions to register a gate Sascha Hauer
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

Linux has clk_register_fixed_factor(). Add the same function with the same
prototype for barebox to ease code porting from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-fixed-factor.c | 7 +++++++
 include/linux/clk.h            | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 4f1a07c629..fd4a3805f1 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -77,6 +77,13 @@ struct clk *clk_fixed_factor(const char *name,
 	return &f->hw.clk;
 }
 
+struct clk *clk_register_fixed_factor(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div)
+{
+	return clk_fixed_factor(name, parent_name, mult, div, flags);
+}
+
 /**
  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
  */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index ba98c5307e..3bb7efdc61 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -509,6 +509,9 @@ extern struct clk_ops clk_fixed_factor_ops;
 struct clk *clk_fixed_factor(const char *name,
 		const char *parent, unsigned int mult, unsigned int div,
 		unsigned flags);
+struct clk *clk_register_fixed_factor(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div);
 
 /**
  * struct clk_fractional_divider - adjustable fractional divider clock
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 16/24] clk: Add Linux functions to register a gate
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (14 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 15/24] clk: Add Linux functions to register a fixed factor clock Sascha Hauer
@ 2021-06-02  9:54 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 17/24] clk: Add Linux functions to register a mux Sascha Hauer
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:54 UTC (permalink / raw)
  To: Barebox List

Linux has clk_register_gate(). Add the same function with the same
prototype for barebox to ease code porting from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-gate.c | 8 ++++++++
 include/linux/clk.h    | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 6e1bf0b316..87b7e73aa6 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -116,3 +116,11 @@ struct clk *clk_gate_inverted(const char *name, const char *parent,
 {
 	return clk_gate(name, parent, reg, shift, flags, CLK_GATE_INVERTED);
 }
+
+struct clk *clk_register_gate(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate_flags, spinlock_t *lock)
+{
+	return clk_gate(name, parent_name, reg, bit_idx, flags, clk_gate_flags);
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 3bb7efdc61..950fecd7e0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -615,6 +615,10 @@ struct clk *clk_gate_inverted(const char *name, const char *parent, void __iomem
 		u8 shift, unsigned flags);
 struct clk *clk_gate_shared(const char *name, const char *parent, const char *shared,
 			    unsigned flags);
+struct clk *clk_register_gate(struct device_d *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx,
+		u8 clk_gate_flags, spinlock_t *lock);
 
 int clk_is_enabled(struct clk *clk);
 int clk_hw_is_enabled(struct clk_hw *hw);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 17/24] clk: Add Linux functions to register a mux
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (15 preceding siblings ...)
  2021-06-02  9:54 ` [PATCH 16/24] clk: Add Linux functions to register a gate Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 18/24] clk: Add CLK_GET_RATE_NOCACHE Sascha Hauer
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Linux has clk_register_mux(). Add the same function with the same
prototype for barebox to ease code porting from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c | 10 ++++++++++
 include/linux/clk.h   |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 464593b619..e7e4369ce0 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -98,3 +98,13 @@ struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
 
 	return m;
 }
+
+struct clk *clk_register_mux(struct device_d *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_mux_flags, spinlock_t *lock)
+{
+	return clk_mux(name, flags, reg, shift, width, parent_names,
+		       num_parents, clk_mux_flags);
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 950fecd7e0..0d2fb488bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -589,6 +589,11 @@ void clk_mux_free(struct clk *clk_mux);
 struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
 		    u8 shift, u8 width, const char * const *parents,
 		    u8 num_parents, unsigned mux_flags);
+struct clk *clk_register_mux(struct device_d *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_mux_flags, spinlock_t *lock);
 
 struct clk_gate {
 	struct clk_hw hw;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 18/24] clk: Add CLK_GET_RATE_NOCACHE
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (16 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 17/24] clk: Add Linux functions to register a mux Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 19/24] clk: Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE Sascha Hauer
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Just add the flag. We don't need any implementation of this flag as we
do not cache the clock rate anyway.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/clk.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0d2fb488bc..c49604fe2d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -333,6 +333,7 @@ static inline void clk_put(struct clk *clk)
 
 #define CLK_SET_RATE_PARENT     (1 << 0) /* propagate rate change up one level */
 #define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
+#define CLK_GET_RATE_NOCACHE    (1 << 6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT (1 << 7) /* don't re-parent on rate change */
 #define CLK_IS_CRITICAL         (1 << 11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 19/24] clk: Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (17 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 18/24] clk: Add CLK_GET_RATE_NOCACHE Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 20/24] clk: implement CLK_SET_RATE_UNGATE Sascha Hauer
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE as done in Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-gate.c      | 8 ++++----
 drivers/clk/imx/clk-gate2.c | 9 ++++-----
 include/linux/clk.h         | 2 +-
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 87b7e73aa6..3cfd707238 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -13,7 +13,7 @@
 static void clk_gate_endisable(struct clk_hw *hw, int enable)
 {
 	struct clk_gate *gate = container_of(hw, struct clk_gate, hw);
-	int set = gate->flags & CLK_GATE_INVERTED ? 1 : 0;
+	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
 	u32 val;
 
 	set ^= enable;
@@ -54,9 +54,9 @@ int clk_gate_is_enabled(struct clk_hw *hw)
 	val = readl(g->reg);
 
 	if (val & (1 << g->shift))
-		return g->flags & CLK_GATE_INVERTED ? 0 : 1;
+		return g->flags & CLK_GATE_SET_TO_DISABLE ? 0 : 1;
 	else
-		return g->flags & CLK_GATE_INVERTED ? 1 : 0;
+		return g->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
 }
 
 struct clk_ops clk_gate_ops = {
@@ -114,7 +114,7 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
 struct clk *clk_gate_inverted(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, unsigned flags)
 {
-	return clk_gate(name, parent, reg, shift, flags, CLK_GATE_INVERTED);
+	return clk_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE);
 }
 
 struct clk *clk_register_gate(struct device_d *dev, const char *name,
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 8866a5365b..af83e93b12 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -18,7 +18,6 @@ struct clk_gate2 {
 	int shift;
 	u8 cgr_val;
 	const char *parent;
-#define CLK_GATE_INVERTED	(1 << 0)
 	unsigned flags;
 };
 
@@ -34,7 +33,7 @@ static int clk_gate2_enable(struct clk_hw *hw)
 
 	val = readl(g->reg);
 
-	if (g->flags & CLK_GATE_INVERTED)
+	if (g->flags & CLK_GATE_SET_TO_DISABLE)
 		val &= ~(3 << g->shift);
 	else
 		val |= g->cgr_val << g->shift;
@@ -51,7 +50,7 @@ static void clk_gate2_disable(struct clk_hw *hw)
 
 	val = readl(g->reg);
 
-	if (g->flags & CLK_GATE_INVERTED)
+	if (g->flags & CLK_GATE_SET_TO_DISABLE)
 		val |= 3 << g->shift;
 	else
 		val &= ~(3 << g->shift);
@@ -67,9 +66,9 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 	val = readl(g->reg);
 
 	if (val & (1 << g->shift))
-		return g->flags & CLK_GATE_INVERTED ? 0 : 1;
+		return g->flags & CLK_GATE_SET_TO_DISABLE ? 0 : 1;
 	else
-		return g->flags & CLK_GATE_INVERTED ? 1 : 0;
+		return g->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
 }
 
 static struct clk_ops clk_gate2_ops = {
diff --git a/include/linux/clk.h b/include/linux/clk.h
index c49604fe2d..d53699a874 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -339,7 +339,7 @@ static inline void clk_put(struct clk *clk)
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
 
-#define CLK_GATE_INVERTED	(1 << 0)
+#define CLK_GATE_SET_TO_DISABLE	(1 << 0)
 #define CLK_GATE_HIWORD_MASK	(1 << 1)
 
 struct clk_ops {
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 20/24] clk: implement CLK_SET_RATE_UNGATE
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (18 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 19/24] clk: Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 21/24] clk: implement set/get phase Sascha Hauer
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Some clocks need to be turned on in oder to change their rate. Implement
CLK_SET_RATE_UNGATE to support these.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk.c   | 12 +++++++++++-
 include/linux/clk.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 74e2f5d783..fe2424dc8a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -172,6 +172,12 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (!clk->ops->set_rate)
 		return -ENOSYS;
 
+	if (clk->flags & CLK_SET_RATE_UNGATE) {
+		ret = clk_enable(clk);
+		if (ret)
+			return ret;
+	}
+
 	parent = clk_get_parent(clk);
 	if (parent) {
 		parent_rate = clk_get_rate(parent);
@@ -179,7 +185,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 		if (clk->flags & CLK_OPS_PARENT_ENABLE) {
 			ret = clk_enable(parent);
 			if (ret)
-				return ret;
+				goto out;
 		}
 	}
 
@@ -190,6 +196,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (parent && clk->flags & CLK_OPS_PARENT_ENABLE)
 		clk_disable(parent);
 
+out:
+	if (clk->flags & CLK_SET_RATE_UNGATE)
+		clk_disable(clk);
+
 	return ret;
 }
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index d53699a874..72971c8e27 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -335,6 +335,7 @@ static inline void clk_put(struct clk *clk)
 #define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
 #define CLK_GET_RATE_NOCACHE    (1 << 6) /* do not use the cached clk rate */
 #define CLK_SET_RATE_NO_REPARENT (1 << 7) /* don't re-parent on rate change */
+#define CLK_SET_RATE_UNGATE     (1 << 10) /* clock needs to run to set rate */
 #define CLK_IS_CRITICAL         (1 << 11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 21/24] clk: implement set/get phase
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (19 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 20/24] clk: implement CLK_SET_RATE_UNGATE Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 22/24] regmap: Add regmap_read_poll_timeout Sascha Hauer
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Linux has clk_set_phase() and clk_get_phase() along with the
corresponding callbacks in struct clk_ops. Implement the same for
barebox as well.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk.c   | 55 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk.h |  5 +++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fe2424dc8a..8b90f30486 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -320,6 +320,61 @@ struct clk_hw *clk_hw_get_parent(struct clk_hw *hw)
 	return clk_to_clk_hw(clk);
 }
 
+/**
+ * clk_set_phase - adjust the phase shift of a clock signal
+ * @clk: clock signal source
+ * @degrees: number of degrees the signal is shifted
+ *
+ * Shifts the phase of a clock signal by the specified
+ * degrees. Returns 0 on success, -EERROR otherwise.
+ *
+ * This function makes no distinction about the input or reference
+ * signal that we adjust the clock signal phase against. For example
+ * phase locked-loop clock signal generators we may shift phase with
+ * respect to feedback clock signal input, but for other cases the
+ * clock phase may be shifted with respect to some other, unspecified
+ * signal.
+ *
+ * Additionally the concept of phase shift does not propagate through
+ * the clock tree hierarchy, which sets it apart from clock rates and
+ * clock accuracy. A parent clock phase attribute does not have an
+ * impact on the phase attribute of a child clock.
+ */
+int clk_set_phase(struct clk *clk, int degrees)
+{
+	if (!clk)
+		return 0;
+
+	/* sanity check degrees */
+	degrees %= 360;
+	if (degrees < 0)
+		degrees += 360;
+
+	if (!clk->ops->set_phase)
+		return -EINVAL;
+
+	return clk->ops->set_phase(clk_to_clk_hw(clk), degrees);
+}
+
+/**
+ * clk_get_phase - return the phase shift of a clock signal
+ * @clk: clock signal source
+ *
+ * Returns the phase shift of a clock node in degrees, otherwise returns
+ * -EERROR.
+ */
+int clk_get_phase(struct clk *clk)
+{
+	int ret;
+
+	if (!clk->ops->get_phase)
+		return 0;
+
+	ret = clk->ops->get_phase(clk_to_clk_hw(clk));
+
+	return ret;
+}
+
 int bclk_register(struct clk *clk)
 {
 	struct clk_hw *hw = clk_to_clk_hw(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 72971c8e27..6b4c368231 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -237,6 +237,9 @@ int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *hwp);
 struct clk *clk_get_parent(struct clk *clk);
 struct clk_hw *clk_hw_get_parent(struct clk_hw *hw);
 
+int clk_set_phase(struct clk *clk, int degrees);
+int clk_get_phase(struct clk *clk);
+
 /**
  * clk_get_sys - get a clock based upon the device name
  * @dev_id: device name
@@ -356,6 +359,8 @@ struct clk_ops {
 	int		(*get_parent)(struct clk_hw *hw);
 	int		(*set_rate)(struct clk_hw *hw, unsigned long,
 				    unsigned long);
+	int		(*set_phase)(struct clk_hw *hw, int degrees);
+	int		(*get_phase)(struct clk_hw *hw);
 };
 
 /**
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 22/24] regmap: Add regmap_read_poll_timeout
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (20 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 21/24] clk: implement set/get phase Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 23/24] clk: rockchip: Update to current Linux Sascha Hauer
  2021-06-02  9:55 ` [PATCH 24/24] clk: Rockchip: Add rk3568 clk support Sascha Hauer
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/regmap.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/regmap.h b/include/regmap.h
index b43cd936fa..057370afc7 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -116,4 +116,28 @@ int regmap_write_bits(struct regmap *map, unsigned int reg,
 int regmap_update_bits(struct regmap *map, unsigned int reg,
 		       unsigned int mask, unsigned int val);
 
+/**
+ * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
+ *
+ * @map: Regmap to read from
+ * @addr: Address to poll
+ * @val: Unsigned integer variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @timeout_us: Timeout in us, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
+ * error return value in case of a error read. In the two former cases,
+ * the last read value at @addr is stored in @val. Must not be called
+ * from atomic context if sleep_us or timeout_us are used.
+ *
+ * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
+ */
+#define regmap_read_poll_timeout(map, addr, val, cond, timeout_us) \
+({ \
+	int __ret, __tmp; \
+	__tmp = read_poll_timeout(regmap_read, __ret, __ret || (cond), \
+			timeout_us, (map), (addr), &(val)); \
+	__ret ?: __tmp; \
+})
+
 #endif /* __REGMAP_H */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 23/24] clk: rockchip: Update to current Linux
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (21 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 22/24] regmap: Add regmap_read_poll_timeout Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-02  9:55 ` [PATCH 24/24] clk: Rockchip: Add rk3568 clk support Sascha Hauer
  23 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

This updates the Rockchip clk code to Linux-5.13-rc1. The code is
unchanged as much as possible. The pre- and post- change hooks are
removed and also the notifier blocks.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/rockchip/Makefile        |   2 +-
 drivers/clk/rockchip/clk-cpu.c       |  80 ++-
 drivers/clk/rockchip/clk-inverter.c  | 107 ++++
 drivers/clk/rockchip/clk-mmc-phase.c | 192 ++++++
 drivers/clk/rockchip/clk-muxgrf.c    |  95 +++
 drivers/clk/rockchip/clk-pll.c       | 839 +++++++++++++++++++++++----
 drivers/clk/rockchip/clk-rk3188.c    | 363 ++++++------
 drivers/clk/rockchip/clk-rk3288.c    | 309 ++++++----
 drivers/clk/rockchip/clk.c           | 489 ++++++++++++----
 drivers/clk/rockchip/clk.h           | 500 ++++++++++++++--
 10 files changed, 2396 insertions(+), 580 deletions(-)
 create mode 100644 drivers/clk/rockchip/clk-inverter.c
 create mode 100644 drivers/clk/rockchip/clk-mmc-phase.c
 create mode 100644 drivers/clk/rockchip/clk-muxgrf.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 5fcf0c2515..9964b331f2 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-y += clk-cpu.o clk-pll.o clk.o
+obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
 obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
 obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index 88564872f5..8b5d4a0330 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -34,8 +34,10 @@
 #include <malloc.h>
 #include <io.h>
 #include <xfuncs.h>
-#include "clk.h"
 #include <linux/barebox-wrapper.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include "clk.h"
 
 /**
  * struct rockchip_cpuclk: information about clock supplied to a CPU core.
@@ -43,31 +45,34 @@
  * @alt_parent:	alternate parent clock to use when switching the speed
  *		of the primary parent clock.
  * @reg_base:	base register for cpu-clock values.
+ * @clk_nb:	clock notifier registered for changes in clock speed of the
+ *		primary parent clock.
  * @rate_count:	number of rates in the rate_table
  * @rate_table:	pll-rates and their associated dividers
  * @reg_data:	cpu-specific register settings
+ * @lock:	clock lock
  */
 struct rockchip_cpuclk {
 	struct clk_hw				hw;
-
 	struct clk				*alt_parent;
 	void __iomem				*reg_base;
 	unsigned int				rate_count;
 	struct rockchip_cpuclk_rate_table	*rate_table;
 	const struct rockchip_cpuclk_reg_data	*reg_data;
+	spinlock_t				*lock;
 };
 
-#define to_rockchip_cpuclk_hw(_hw) container_of(_hw, struct rockchip_cpuclk, hw)
+#define to_rockchip_cpuclk_hw(hw) container_of(hw, struct rockchip_cpuclk, hw)
 
 static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
 					unsigned long parent_rate)
 {
 	struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_hw(hw);
 	const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
-	u32 clksel0 = readl(cpuclk->reg_base + reg_data->core_reg);
+	u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg[0]);
 
-	clksel0 >>= reg_data->div_core_shift;
-	clksel0 &= reg_data->div_core_mask;
+	clksel0 >>= reg_data->div_core_shift[0];
+	clksel0 &= reg_data->div_core_mask[0];
 	return parent_rate / (clksel0 + 1);
 }
 
@@ -76,17 +81,18 @@ static const struct clk_ops rockchip_cpuclk_ops = {
 };
 
 struct clk *rockchip_clk_register_cpuclk(const char *name,
-			const char **parent_names, u8 num_parents,
+			const char *const *parent_names, u8 num_parents,
 			const struct rockchip_cpuclk_reg_data *reg_data,
 			const struct rockchip_cpuclk_rate_table *rates,
-			int nrates, void __iomem *reg_base)
+			int nrates, void __iomem *reg_base, spinlock_t *lock)
 {
 	struct rockchip_cpuclk *cpuclk;
-	struct clk *clk;
+	struct clk_init_data init;
+	struct clk *clk, *cclk;
 	int ret;
 
-	if (num_parents != 2) {
-		pr_err("%s: needs two parent clocks\n", __func__);
+	if (num_parents < 2) {
+		pr_err("%s: needs at least two parent clocks\n", __func__);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -94,21 +100,28 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 	if (!cpuclk)
 		return ERR_PTR(-ENOMEM);
 
-	cpuclk->hw.clk.name = name;
-	cpuclk->hw.clk.parent_names = &parent_names[0];
-	cpuclk->hw.clk.num_parents = 1;
-	cpuclk->hw.clk.ops = &rockchip_cpuclk_ops;
+	init.name = name;
+	init.parent_names = &parent_names[reg_data->mux_core_main];
+	init.num_parents = 1;
+	init.ops = &rockchip_cpuclk_ops;
 
 	/* only allow rate changes when we have a rate table */
-	cpuclk->hw.clk.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0;
+	init.flags = (nrates > 0) ? CLK_SET_RATE_PARENT : 0;
+
+	/* disallow automatic parent changes by ccf */
+	init.flags |= CLK_SET_RATE_NO_REPARENT;
+
+	init.flags |= CLK_GET_RATE_NOCACHE;
 
 	cpuclk->reg_base = reg_base;
+	cpuclk->lock = lock;
 	cpuclk->reg_data = reg_data;
+	cpuclk->hw.init = &init;
 
-	cpuclk->alt_parent = __clk_lookup(parent_names[1]);
+	cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]);
 	if (!cpuclk->alt_parent) {
-		pr_err("%s: could not lookup alternate parent\n",
-		       __func__);
+		pr_err("%s: could not lookup alternate parent: (%d)\n",
+		       __func__, reg_data->mux_core_alt);
 		ret = -EINVAL;
 		goto free_cpuclk;
 	}
@@ -120,37 +133,40 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 		goto free_cpuclk;
 	}
 
-	clk = __clk_lookup(parent_names[0]);
+	clk = __clk_lookup(parent_names[reg_data->mux_core_main]);
 	if (!clk) {
-		pr_err("%s: could not lookup parent clock %s\n",
-		       __func__, parent_names[0]);
+		pr_err("%s: could not lookup parent clock: (%d) %s\n",
+		       __func__, reg_data->mux_core_main,
+		       parent_names[reg_data->mux_core_main]);
 		ret = -EINVAL;
-		goto free_cpuclk;
+		goto free_alt_parent;
 	}
 
 	if (nrates > 0) {
 		cpuclk->rate_count = nrates;
-		cpuclk->rate_table = xmemdup(rates,
-					     sizeof(*rates) * nrates
-					     );
+		cpuclk->rate_table = kmemdup(rates,
+					     sizeof(*rates) * nrates,
+					     GFP_KERNEL);
 		if (!cpuclk->rate_table) {
-			pr_err("%s: could not allocate memory for cpuclk rates\n",
-			       __func__);
 			ret = -ENOMEM;
-			goto free_cpuclk;
+			goto unregister_notifier;
 		}
 	}
 
-	ret = bclk_register(&cpuclk->hw.clk);
-	if (ret) {
+	cclk = clk_register(NULL, &cpuclk->hw);
+	if (IS_ERR(cclk)) {
 		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
+		ret = PTR_ERR(cclk);
 		goto free_rate_table;
 	}
 
-	return &cpuclk->hw.clk;
+	return cclk;
 
 free_rate_table:
 	kfree(cpuclk->rate_table);
+unregister_notifier:
+free_alt_parent:
+	clk_disable(cpuclk->alt_parent);
 free_cpuclk:
 	kfree(cpuclk);
 	return ERR_PTR(ret);
diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c
new file mode 100644
index 0000000000..7cdcf15fd8
--- /dev/null
+++ b/drivers/clk/rockchip/clk-inverter.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2015 Heiko Stuebner <heiko@sntech.de>
+ */
+
+#include <common.h>
+#include <of.h>
+#include <malloc.h>
+#include <io.h>
+#include <xfuncs.h>
+#include <linux/barebox-wrapper.h>
+#include <linux/clk.h>
+#include <regmap.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_inv_clock {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	int		shift;
+	int		flags;
+	spinlock_t	*lock;
+};
+
+#define to_inv_clock(_hw) container_of(_hw, struct rockchip_inv_clock, hw)
+
+#define INVERTER_MASK 0x1
+
+static int rockchip_inv_get_phase(struct clk_hw *hw)
+{
+	struct rockchip_inv_clock *inv_clock = to_inv_clock(hw);
+	u32 val;
+
+	val = readl(inv_clock->reg) >> inv_clock->shift;
+	val &= INVERTER_MASK;
+	return val ? 180 : 0;
+}
+
+static int rockchip_inv_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct rockchip_inv_clock *inv_clock = to_inv_clock(hw);
+	u32 val;
+
+	if (degrees % 180 == 0) {
+		val = !!degrees;
+	} else {
+		pr_err("%s: unsupported phase %d for %s\n",
+		       __func__, degrees, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	if (inv_clock->flags & ROCKCHIP_INVERTER_HIWORD_MASK) {
+		writel(HIWORD_UPDATE(val, INVERTER_MASK, inv_clock->shift),
+		       inv_clock->reg);
+	} else {
+		unsigned long flags;
+		u32 reg;
+
+		spin_lock_irqsave(inv_clock->lock, flags);
+
+		reg = readl(inv_clock->reg);
+		reg &= ~BIT(inv_clock->shift);
+		reg |= val;
+		writel(reg, inv_clock->reg);
+
+		spin_unlock_irqrestore(inv_clock->lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct clk_ops rockchip_inv_clk_ops = {
+	.get_phase	= rockchip_inv_get_phase,
+	.set_phase	= rockchip_inv_set_phase,
+};
+
+struct clk *rockchip_clk_register_inverter(const char *name,
+				const char *const *parent_names, u8 num_parents,
+				void __iomem *reg, int shift, int flags,
+				spinlock_t *lock)
+{
+	struct clk_init_data init;
+	struct rockchip_inv_clock *inv_clock;
+	struct clk *clk;
+
+	inv_clock = kzalloc(sizeof(*inv_clock), GFP_KERNEL);
+	if (!inv_clock)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.num_parents = num_parents;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = parent_names;
+	init.ops = &rockchip_inv_clk_ops;
+
+	inv_clock->hw.init = &init;
+	inv_clock->reg = reg;
+	inv_clock->shift = shift;
+	inv_clock->flags = flags;
+	inv_clock->lock = lock;
+
+	clk = clk_register(NULL, &inv_clock->hw);
+	if (IS_ERR(clk))
+		kfree(inv_clock);
+
+	return clk;
+}
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
new file mode 100644
index 0000000000..822189a2fd
--- /dev/null
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2014 Google, Inc
+ * Author: Alexandru M Stan <amstan@chromium.org>
+ */
+
+#include <common.h>
+#include <of.h>
+#include <malloc.h>
+#include <io.h>
+#include <xfuncs.h>
+#include <linux/barebox-wrapper.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_mmc_clock {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	int		id;
+	int		shift;
+	int		cached_phase;
+};
+
+#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw)
+
+#define RK3288_MMC_CLKGEN_DIV 2
+
+static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	return parent_rate / RK3288_MMC_CLKGEN_DIV;
+}
+
+#define ROCKCHIP_MMC_DELAY_SEL BIT(10)
+#define ROCKCHIP_MMC_DEGREE_MASK 0x3
+#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
+#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+
+#define PSECS_PER_SEC 1000000000000LL
+
+/*
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
+ */
+#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
+
+static int rockchip_mmc_get_phase(struct clk_hw *hw)
+{
+	struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
+	unsigned long rate = clk_hw_get_rate(hw);
+	u32 raw_value;
+	u16 degrees;
+	u32 delay_num = 0;
+
+	/* Constant signal, no measurable phase shift */
+	if (!rate)
+		return 0;
+
+	raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
+
+	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
+
+	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
+		/* degrees/delaynum * 1000000 */
+		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
+					36 * (rate / 10000);
+
+		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
+		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
+		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 1000000);
+	}
+
+	return degrees % 360;
+}
+
+static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
+	unsigned long rate = clk_hw_get_rate(hw);
+	u8 nineties, remainder;
+	u8 delay_num;
+	u32 raw_value;
+	u32 delay;
+
+	/*
+	 * The below calculation is based on the output clock from
+	 * MMC host to the card, which expects the phase clock inherits
+	 * the clock rate from its parent, namely the output clock
+	 * provider of MMC host. However, things may go wrong if
+	 * (1) It is orphan.
+	 * (2) It is assigned to the wrong parent.
+	 *
+	 * This check help debug the case (1), which seems to be the
+	 * most likely problem we often face and which makes it difficult
+	 * for people to debug unstable mmc tuning results.
+	 */
+	if (!rate) {
+		pr_err("%s: invalid clk rate\n", __func__);
+		return -EINVAL;
+	}
+
+	nineties = degrees / 90;
+	remainder = (degrees % 90);
+
+	/*
+	 * Due to the inexact nature of the "fine" delay, we might
+	 * actually go non-monotonic.  We don't go _too_ monotonic
+	 * though, so we should be OK.  Here are options of how we may
+	 * work:
+	 *
+	 * Ideally we end up with:
+	 *   1.0, 2.0, ..., 69.0, 70.0, ...,  89.0, 90.0
+	 *
+	 * On one extreme (if delay is actually 44ps):
+	 *   .73, 1.5, ..., 50.6, 51.3, ...,  65.3, 90.0
+	 * The other (if delay is actually 77ps):
+	 *   1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
+	 *
+	 * It's possible we might make a delay that is up to 25
+	 * degrees off from what we think we're making.  That's OK
+	 * though because we should be REALLY far from any bad range.
+	 */
+
+	/*
+	 * Convert to delay; do a little extra work to make sure we
+	 * don't overflow 32-bit / 64-bit numbers.
+	 */
+	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
+	delay *= remainder;
+	delay = DIV_ROUND_CLOSEST(delay,
+			(rate / 1000) * 36 *
+				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
+
+	delay_num = (u8) min_t(u32, delay, 255);
+
+	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
+	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
+	raw_value |= nineties;
+	writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
+	       mmc_clock->reg);
+
+	pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
+		clk_hw_get_name(hw), degrees, delay_num,
+		mmc_clock->reg, raw_value>>(mmc_clock->shift),
+		rockchip_mmc_get_phase(hw)
+	);
+
+	return 0;
+}
+
+static const struct clk_ops rockchip_mmc_clk_ops = {
+	.recalc_rate	= rockchip_mmc_recalc,
+	.get_phase	= rockchip_mmc_get_phase,
+	.set_phase	= rockchip_mmc_set_phase,
+};
+
+struct clk *rockchip_clk_register_mmc(const char *name,
+				const char *const *parent_names, u8 num_parents,
+				void __iomem *reg, int shift)
+{
+	struct clk_init_data init;
+	struct rockchip_mmc_clock *mmc_clock;
+	struct clk *clk;
+	int ret;
+
+	mmc_clock = kzalloc(sizeof(*mmc_clock), GFP_KERNEL);
+	if (!mmc_clock)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.flags = 0;
+	init.num_parents = num_parents;
+	init.parent_names = parent_names;
+	init.ops = &rockchip_mmc_clk_ops;
+
+	mmc_clock->hw.init = &init;
+	mmc_clock->reg = reg;
+	mmc_clock->shift = shift;
+
+	clk = clk_register(NULL, &mmc_clock->hw);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto err_register;
+	}
+
+	return clk;
+
+err_register:
+	kfree(mmc_clock);
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/rockchip/clk-muxgrf.c b/drivers/clk/rockchip/clk-muxgrf.c
new file mode 100644
index 0000000000..f06fa69514
--- /dev/null
+++ b/drivers/clk/rockchip/clk-muxgrf.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <of.h>
+#include <malloc.h>
+#include <io.h>
+#include <xfuncs.h>
+#include <linux/barebox-wrapper.h>
+#include <linux/clk.h>
+#include <regmap.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_muxgrf_clock {
+	struct clk_hw		hw;
+	struct regmap		*regmap;
+	u32			reg;
+	u32			shift;
+	u32			width;
+	int			flags;
+};
+
+#define to_muxgrf_clock(_hw) container_of(_hw, struct rockchip_muxgrf_clock, hw)
+
+static int rockchip_muxgrf_get_parent(struct clk_hw *hw)
+{
+	struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
+	unsigned int mask = GENMASK(mux->width - 1, 0);
+	unsigned int val;
+
+	regmap_read(mux->regmap, mux->reg, &val);
+
+	val >>= mux->shift;
+	val &= mask;
+
+	return val;
+}
+
+static int rockchip_muxgrf_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
+	unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+	unsigned int val;
+
+	val = index;
+	val <<= mux->shift;
+
+	if (mux->flags & CLK_MUX_HIWORD_MASK)
+		return regmap_write(mux->regmap, mux->reg, val | (mask << 16));
+	else
+		return regmap_update_bits(mux->regmap, mux->reg, mask, val);
+}
+
+static const struct clk_ops rockchip_muxgrf_clk_ops = {
+	.get_parent = rockchip_muxgrf_get_parent,
+	.set_parent = rockchip_muxgrf_set_parent,
+};
+
+struct clk *rockchip_clk_register_muxgrf(const char *name,
+				const char *const *parent_names, u8 num_parents,
+				int flags, struct regmap *regmap, int reg,
+				int shift, int width, int mux_flags)
+{
+	struct rockchip_muxgrf_clock *muxgrf_clock;
+	struct clk_init_data init;
+	struct clk *clk;
+
+	if (IS_ERR(regmap)) {
+		pr_err("%s: regmap not available\n", __func__);
+		return ERR_PTR(-ENOTSUPP);
+	}
+
+	muxgrf_clock = kzalloc(sizeof(*muxgrf_clock), GFP_KERNEL);
+	if (!muxgrf_clock)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.flags = flags;
+	init.num_parents = num_parents;
+	init.parent_names = parent_names;
+	init.ops = &rockchip_muxgrf_clk_ops;
+
+	muxgrf_clock->hw.init = &init;
+	muxgrf_clock->regmap = regmap;
+	muxgrf_clock->reg = reg;
+	muxgrf_clock->shift = shift;
+	muxgrf_clock->width = width;
+	muxgrf_clock->flags = mux_flags;
+
+	clk = clk_register(NULL, &muxgrf_clock->hw);
+	if (IS_ERR(clk))
+		kfree(muxgrf_clock);
+
+	return clk;
+}
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 9a430f928b..fdbb016e7f 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
  */
 
 #include <linux/math64.h>
@@ -14,16 +17,19 @@
 #include <linux/barebox-wrapper.h>
 #include "clk.h"
 #include <xfuncs.h>
+#include <regmap.h>
+#include <linux/iopoll.h>
 
-#define PLL_MODE_MASK		0x3
+#define PLL_MODE_WIDTH		2
 #define PLL_MODE_SLOW		0x0
 #define PLL_MODE_NORM		0x1
 #define PLL_MODE_DEEP		0x2
+#define PLL_RK3328_MODE_WIDTH	1
 
 struct rockchip_clk_pll {
 	struct clk_hw		hw;
 
-	struct clk_hw		pll_mux;
+	struct clk_mux		pll_mux;
 	const struct clk_ops	*pll_mux_ops;
 
 	void __iomem		*reg_base;
@@ -33,7 +39,9 @@ struct rockchip_clk_pll {
 	u8			flags;
 	const struct rockchip_pll_rate_table *rate_table;
 	unsigned int		rate_count;
-	char			pll_name[20];
+	spinlock_t		*lock;
+
+	struct rockchip_clk_provider *ctx;
 };
 
 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
@@ -74,26 +82,282 @@ static long rockchip_pll_round_rate(struct clk_hw *hw,
  * The calling set_rate function is responsible for making sure the
  * grf regmap is available.
  */
-#define RK3188_PLL_LOCK_REG     0x200080ac
-
 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 {
-	int delay = 24000000;
-	int val;
+	struct regmap *grf = pll->ctx->grf;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,
+				       val & BIT(pll->lock_shift), 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
+
+	return ret;
+}
+
+/*
+ * PLL used in RK3036
+ */
+
+#define RK3036_PLLCON(i)			(i * 0x4)
+#define RK3036_PLLCON0_FBDIV_MASK		0xfff
+#define RK3036_PLLCON0_FBDIV_SHIFT		0
+#define RK3036_PLLCON0_POSTDIV1_MASK		0x7
+#define RK3036_PLLCON0_POSTDIV1_SHIFT		12
+#define RK3036_PLLCON1_REFDIV_MASK		0x3f
+#define RK3036_PLLCON1_REFDIV_SHIFT		0
+#define RK3036_PLLCON1_POSTDIV2_MASK		0x7
+#define RK3036_PLLCON1_POSTDIV2_SHIFT		6
+#define RK3036_PLLCON1_LOCK_STATUS		BIT(10)
+#define RK3036_PLLCON1_DSMPD_MASK		0x1
+#define RK3036_PLLCON1_DSMPD_SHIFT		12
+#define RK3036_PLLCON1_PWRDOWN			BIT(13)
+#define RK3036_PLLCON2_FRAC_MASK		0xffffff
+#define RK3036_PLLCON2_FRAC_SHIFT		0
+
+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+	u32 pllcon;
+	int ret;
+
+	/*
+	 * Lock time typical 250, max 500 input clock cycles @24MHz
+	 * So define a very safe maximum of 1000us, meaning 24000 cycles.
+	 */
+	ret = readl_poll_timeout(pll->reg_base + RK3036_PLLCON(1),
+					 pllcon,
+					 pllcon & RK3036_PLLCON1_LOCK_STATUS,
+					 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
+
+	return ret;
+}
+
+static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
+					struct rockchip_pll_rate_table *rate)
+{
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
+	rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
+				& RK3036_PLLCON0_FBDIV_MASK);
+	rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
+				& RK3036_PLLCON0_POSTDIV1_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
+	rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
+				& RK3036_PLLCON1_REFDIV_MASK);
+	rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
+				& RK3036_PLLCON1_POSTDIV2_MASK);
+	rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
+				& RK3036_PLLCON1_DSMPD_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
+	rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
+				& RK3036_PLLCON2_FRAC_MASK);
+}
+
+static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
+						     unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	struct rockchip_pll_rate_table cur;
+	u64 rate64 = prate;
+
+	rockchip_rk3036_pll_get_params(pll, &cur);
+
+	rate64 *= cur.fbdiv;
+	do_div(rate64, cur.refdiv);
+
+	if (cur.dsmpd == 0) {
+		/* fractional mode */
+		u64 frac_rate64 = prate * cur.frac;
+
+		do_div(frac_rate64, cur.refdiv);
+		rate64 += frac_rate64 >> 24;
+	}
+
+	do_div(rate64, cur.postdiv1);
+	do_div(rate64, cur.postdiv2);
+
+	return (unsigned long)rate64;
+}
+
+static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
+				const struct rockchip_pll_rate_table *rate)
+{
+	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	struct rockchip_pll_rate_table cur;
+	u32 pllcon;
+	int rate_change_remuxed = 0;
+	int cur_parent;
+	int ret;
+
+	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		__func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
+		rate->postdiv2, rate->dsmpd, rate->frac);
+
+	rockchip_rk3036_pll_get_params(pll, &cur);
+	cur.rate = 0;
+
+	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
+	if (cur_parent == PLL_MODE_NORM) {
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
+		rate_change_remuxed = 1;
+	}
+
+	/* update pll values */
+	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
+					  RK3036_PLLCON0_FBDIV_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
+					     RK3036_PLLCON0_POSTDIV1_SHIFT),
+		       pll->reg_base + RK3036_PLLCON(0));
+
+	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
+						   RK3036_PLLCON1_REFDIV_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
+						     RK3036_PLLCON1_POSTDIV2_SHIFT) |
+		       HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
+						  RK3036_PLLCON1_DSMPD_SHIFT),
+		       pll->reg_base + RK3036_PLLCON(1));
+
+	/* GPLL CON2 is not HIWORD_MASK */
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
+	pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
+	pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
+	writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
 
 	/* wait for the pll to lock */
-	while (delay > 0) {
-		val = readl(RK3188_PLL_LOCK_REG);
-		if (val & BIT(pll->lock_shift))
+	ret = rockchip_rk3036_pll_wait_lock(pll);
+	if (ret) {
+		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
+			__func__);
+		rockchip_rk3036_pll_set_params(pll, &cur);
+	}
+
+	if (rate_change_remuxed)
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
+
+	return ret;
+}
+
+static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+
+	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
+		 __func__, clk_hw_get_name(hw), drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	return rockchip_rk3036_pll_set_params(pll, rate);
+}
+
+static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+	writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
+	       pll->reg_base + RK3036_PLLCON(1));
+	rockchip_rk3036_pll_wait_lock(pll);
+
+	return 0;
+}
+
+static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+	writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
+			     RK3036_PLLCON1_PWRDOWN, 0),
+	       pll->reg_base + RK3036_PLLCON(1));
+}
+
+static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
+
+	return !(pllcon & RK3036_PLLCON1_PWRDOWN);
+}
+
+static int rockchip_rk3036_pll_init(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	struct rockchip_pll_rate_table cur;
+	unsigned long drate;
+
+	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
+		return 0;
+
+	drate = clk_hw_get_rate(hw);
+	rate = rockchip_get_pll_settings(pll, drate);
+
+	/* when no rate setting for the current rate, rely on clk_set_rate */
+	if (!rate)
+		return 0;
+
+	rockchip_rk3036_pll_get_params(pll, &cur);
+
+	pr_debug("%s: pll %s@%lu: Hz\n", __func__, clk_hw_get_name(hw),
+		 drate);
+	pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
+		 cur.dsmpd, cur.frac);
+	pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
+		 rate->dsmpd, rate->frac);
+
+	if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
+		rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
+		rate->dsmpd != cur.dsmpd ||
+		(!cur.dsmpd && (rate->frac != cur.frac))) {
+		struct clk *parent = clk_get_parent(clk_hw_to_clk(hw));
+
+		if (!parent) {
+			pr_warn("%s: parent of %s not available\n",
+				__func__, clk_hw_get_name(hw));
 			return 0;
-		delay--;
+		}
+
+		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
+			 __func__, clk_hw_get_name(hw));
+		rockchip_rk3036_pll_set_params(pll, rate);
 	}
 
-	pr_err("%s: timeout waiting for pll to lock\n", __func__);
-	return -ETIMEDOUT;
+	return 0;
 }
 
-/**
+static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
+	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
+	.enable = rockchip_rk3036_pll_enable,
+	.disable = rockchip_rk3036_pll_disable,
+	.is_enabled = rockchip_rk3036_pll_is_enabled,
+};
+
+static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
+	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
+	.round_rate = rockchip_pll_round_rate,
+	.set_rate = rockchip_rk3036_pll_set_rate,
+	.enable = rockchip_rk3036_pll_enable,
+	.disable = rockchip_rk3036_pll_disable,
+	.is_enabled = rockchip_rk3036_pll_is_enabled,
+	.init = rockchip_rk3036_pll_init,
+};
+
+/*
  * PLL used in RK3066, RK3188 and RK3288
  */
 
@@ -106,75 +370,75 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3066_PLLCON0_NR_SHIFT		8
 #define RK3066_PLLCON1_NF_MASK		0x1fff
 #define RK3066_PLLCON1_NF_SHIFT		0
-#define RK3066_PLLCON2_BWADJ_MASK	0xfff
-#define RK3066_PLLCON2_BWADJ_SHIFT	0
+#define RK3066_PLLCON2_NB_MASK		0xfff
+#define RK3066_PLLCON2_NB_SHIFT		0
 #define RK3066_PLLCON3_RESET		(1 << 5)
 #define RK3066_PLLCON3_PWRDOWN		(1 << 1)
 #define RK3066_PLLCON3_BYPASS		(1 << 0)
 
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
+					struct rockchip_pll_rate_table *rate)
+{
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+	rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+				& RK3066_PLLCON0_NR_MASK) + 1;
+	rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+				& RK3066_PLLCON0_OD_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+	rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+				& RK3066_PLLCON1_NF_MASK) + 1;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+	rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+				& RK3066_PLLCON2_NB_MASK) + 1;
+}
+
 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
 						     unsigned long prate)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	u64 nf, nr, no, rate64 = prate;
+	struct rockchip_pll_rate_table cur;
+	u64 rate64 = prate;
 	u32 pllcon;
 
-	pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
+	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
 	if (pllcon & RK3066_PLLCON3_BYPASS) {
 		pr_debug("%s: pll %s is bypassed\n", __func__,
 			clk_hw_get_name(hw));
 		return prate;
 	}
 
-	pllcon = readl(pll->reg_base + RK3066_PLLCON(1));
-	nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
-
-	pllcon = readl(pll->reg_base + RK3066_PLLCON(0));
-	nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
-	no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
-
-	rate64 *= (nf + 1);
-	do_div(rate64, nr + 1);
-	do_div(rate64, no + 1);
+	rockchip_rk3066_pll_get_params(pll, &cur);
 
-	pr_debug("%s: %s rate=%lu\n",
-		 __func__, clk_hw_get_name(hw), (unsigned long)rate64);
+	rate64 *= cur.nf;
+	do_div(rate64, cur.nr);
+	do_div(rate64, cur.no);
 
 	return (unsigned long)rate64;
 }
 
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
-					unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
+				const struct rockchip_pll_rate_table *rate)
 {
-	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-	const struct rockchip_pll_rate_table *rate;
-	unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-	struct clk_hw *pll_mux = &pll->pll_mux;
 	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	struct rockchip_pll_rate_table cur;
 	int rate_change_remuxed = 0;
 	int cur_parent;
 	int ret;
 
-	if (old_rate == drate)
-		return 0;
-
-	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
-		 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
-	/* Get required rate settings from table */
-	rate = rockchip_get_pll_settings(pll, drate);
-	if (!rate) {
-		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, clk_hw_get_name(hw));
-		return -EINVAL;
-	}
-
 	pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
 		 __func__, rate->rate, rate->nr, rate->no, rate->nf);
 
-	cur_parent = pll_mux_ops->get_parent(pll_mux);
+	rockchip_rk3066_pll_get_params(pll, &cur);
+	cur.rate = 0;
+
+	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
 	if (cur_parent == PLL_MODE_NORM) {
-		pll_mux_ops->set_parent(pll_mux, PLL_MODE_SLOW);
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
 		rate_change_remuxed = 1;
 	}
 
@@ -189,11 +453,11 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 					   RK3066_PLLCON0_OD_SHIFT),
 	       pll->reg_base + RK3066_PLLCON(0));
 
-	writel(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
+	writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
 						   RK3066_PLLCON1_NF_SHIFT),
 		       pll->reg_base + RK3066_PLLCON(1));
-	writel(HIWORD_UPDATE(rate->bwadj, RK3066_PLLCON2_BWADJ_MASK,
-						  RK3066_PLLCON2_BWADJ_SHIFT),
+	writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,
+						   RK3066_PLLCON2_NB_SHIFT),
 		       pll->reg_base + RK3066_PLLCON(2));
 
 	/* leave reset and wait the reset_delay */
@@ -204,23 +468,44 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	/* wait for the pll to lock */
 	ret = rockchip_pll_wait_lock(pll);
 	if (ret) {
-		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
-			__func__, old_rate);
-		rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
+			__func__);
+		rockchip_rk3066_pll_set_params(pll, &cur);
 	}
 
 	if (rate_change_remuxed)
-		pll_mux_ops->set_parent(pll_mux, PLL_MODE_NORM);
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
 
 	return ret;
 }
 
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+
+	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
+		 __func__, clk_hw_get_name(hw), drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
 	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
 
 	writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
 	       pll->reg_base + RK3066_PLLCON(3));
+	rockchip_pll_wait_lock(pll);
 
 	return 0;
 }
@@ -242,6 +527,38 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
 	return !(pllcon & RK3066_PLLCON3_PWRDOWN);
 }
 
+static int rockchip_rk3066_pll_init(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	struct rockchip_pll_rate_table cur;
+	unsigned long drate;
+
+	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
+		return 0;
+
+	drate = clk_hw_get_rate(hw);
+	rate = rockchip_get_pll_settings(pll, drate);
+
+	/* when no rate setting for the current rate, rely on clk_set_rate */
+	if (!rate)
+		return 0;
+
+	rockchip_rk3066_pll_get_params(pll, &cur);
+
+	pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
+		 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+		 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+	if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
+						     || rate->nb != cur.nb) {
+		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
+			 __func__, clk_hw_get_name(hw));
+		rockchip_rk3066_pll_set_params(pll, rate);
+	}
+
+	return 0;
+}
+
 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
 	.recalc_rate = rockchip_rk3066_pll_recalc_rate,
 	.enable = rockchip_rk3066_pll_enable,
@@ -256,44 +573,351 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
 	.enable = rockchip_rk3066_pll_enable,
 	.disable = rockchip_rk3066_pll_disable,
 	.is_enabled = rockchip_rk3066_pll_is_enabled,
+	.init = rockchip_rk3066_pll_init,
+};
+
+/*
+ * PLL used in RK3399
+ */
+
+#define RK3399_PLLCON(i)			(i * 0x4)
+#define RK3399_PLLCON0_FBDIV_MASK		0xfff
+#define RK3399_PLLCON0_FBDIV_SHIFT		0
+#define RK3399_PLLCON1_REFDIV_MASK		0x3f
+#define RK3399_PLLCON1_REFDIV_SHIFT		0
+#define RK3399_PLLCON1_POSTDIV1_MASK		0x7
+#define RK3399_PLLCON1_POSTDIV1_SHIFT		8
+#define RK3399_PLLCON1_POSTDIV2_MASK		0x7
+#define RK3399_PLLCON1_POSTDIV2_SHIFT		12
+#define RK3399_PLLCON2_FRAC_MASK		0xffffff
+#define RK3399_PLLCON2_FRAC_SHIFT		0
+#define RK3399_PLLCON2_LOCK_STATUS		BIT(31)
+#define RK3399_PLLCON3_PWRDOWN			BIT(0)
+#define RK3399_PLLCON3_DSMPD_MASK		0x1
+#define RK3399_PLLCON3_DSMPD_SHIFT		3
+
+static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+	u32 pllcon;
+	int ret;
+
+	/*
+	 * Lock time typical 250, max 500 input clock cycles @24MHz
+	 * So define a very safe maximum of 1000us, meaning 24000 cycles.
+	 */
+	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),
+					 pllcon,
+					 pllcon & RK3399_PLLCON2_LOCK_STATUS,
+					 1000);
+	if (ret)
+		pr_err("%s: timeout waiting for pll to lock\n", __func__);
+
+	return ret;
+}
+
+static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
+					struct rockchip_pll_rate_table *rate)
+{
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
+	rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
+				& RK3399_PLLCON0_FBDIV_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
+	rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
+				& RK3399_PLLCON1_REFDIV_MASK);
+	rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
+				& RK3399_PLLCON1_POSTDIV1_MASK);
+	rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
+				& RK3399_PLLCON1_POSTDIV2_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
+	rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
+				& RK3399_PLLCON2_FRAC_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
+	rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
+				& RK3399_PLLCON3_DSMPD_MASK);
+}
+
+static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
+						     unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	struct rockchip_pll_rate_table cur;
+	u64 rate64 = prate;
+
+	rockchip_rk3399_pll_get_params(pll, &cur);
+
+	rate64 *= cur.fbdiv;
+	do_div(rate64, cur.refdiv);
+
+	if (cur.dsmpd == 0) {
+		/* fractional mode */
+		u64 frac_rate64 = prate * cur.frac;
+
+		do_div(frac_rate64, cur.refdiv);
+		rate64 += frac_rate64 >> 24;
+	}
+
+	do_div(rate64, cur.postdiv1);
+	do_div(rate64, cur.postdiv2);
+
+	return (unsigned long)rate64;
+}
+
+static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
+				const struct rockchip_pll_rate_table *rate)
+{
+	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	struct rockchip_pll_rate_table cur;
+	u32 pllcon;
+	int rate_change_remuxed = 0;
+	int cur_parent;
+	int ret;
+
+	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		__func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
+		rate->postdiv2, rate->dsmpd, rate->frac);
+
+	rockchip_rk3399_pll_get_params(pll, &cur);
+	cur.rate = 0;
+
+	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
+	if (cur_parent == PLL_MODE_NORM) {
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
+		rate_change_remuxed = 1;
+	}
+
+	/* update pll values */
+	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
+						  RK3399_PLLCON0_FBDIV_SHIFT),
+		       pll->reg_base + RK3399_PLLCON(0));
+
+	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
+						   RK3399_PLLCON1_REFDIV_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
+						     RK3399_PLLCON1_POSTDIV1_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
+						     RK3399_PLLCON1_POSTDIV2_SHIFT),
+		       pll->reg_base + RK3399_PLLCON(1));
+
+	/* xPLL CON2 is not HIWORD_MASK */
+	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
+	pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
+	pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
+	writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
+
+	writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
+					    RK3399_PLLCON3_DSMPD_SHIFT),
+		       pll->reg_base + RK3399_PLLCON(3));
+
+	/* wait for the pll to lock */
+	ret = rockchip_rk3399_pll_wait_lock(pll);
+	if (ret) {
+		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
+			__func__);
+		rockchip_rk3399_pll_set_params(pll, &cur);
+	}
+
+	if (rate_change_remuxed)
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
+
+	return ret;
+}
+
+static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+
+	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
+		 __func__, clk_hw_get_name(hw), drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, clk_hw_get_name(hw));
+		return -EINVAL;
+	}
+
+	return rockchip_rk3399_pll_set_params(pll, rate);
+}
+
+static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+	writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
+	       pll->reg_base + RK3399_PLLCON(3));
+	rockchip_rk3399_pll_wait_lock(pll);
+
+	return 0;
+}
+
+static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+	writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
+			     RK3399_PLLCON3_PWRDOWN, 0),
+	       pll->reg_base + RK3399_PLLCON(3));
+}
+
+static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
+
+	return !(pllcon & RK3399_PLLCON3_PWRDOWN);
+}
+
+static int rockchip_rk3399_pll_init(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	struct rockchip_pll_rate_table cur;
+	unsigned long drate;
+
+	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
+		return 0;
+
+	drate = clk_hw_get_rate(hw);
+	rate = rockchip_get_pll_settings(pll, drate);
+
+	/* when no rate setting for the current rate, rely on clk_set_rate */
+	if (!rate)
+		return 0;
+
+	rockchip_rk3399_pll_get_params(pll, &cur);
+
+	pr_debug("%s: pll %s@%lu: Hz\n", __func__, clk_hw_get_name(hw),
+		 drate);
+	pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
+		 cur.dsmpd, cur.frac);
+	pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
+		 rate->dsmpd, rate->frac);
+
+	if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
+		rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
+		rate->dsmpd != cur.dsmpd ||
+		(!cur.dsmpd && (rate->frac != cur.frac))) {
+		struct clk *parent = clk_get_parent(clk_hw_to_clk(hw));
+
+		if (!parent) {
+			pr_warn("%s: parent of %s not available\n",
+				__func__, clk_hw_get_name(hw));
+			return 0;
+		}
+
+		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
+			 __func__, clk_hw_get_name(hw));
+		rockchip_rk3399_pll_set_params(pll, rate);
+	}
+
+	return 0;
+}
+
+static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
+	.recalc_rate = rockchip_rk3399_pll_recalc_rate,
+	.enable = rockchip_rk3399_pll_enable,
+	.disable = rockchip_rk3399_pll_disable,
+	.is_enabled = rockchip_rk3399_pll_is_enabled,
+};
+
+static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
+	.recalc_rate = rockchip_rk3399_pll_recalc_rate,
+	.round_rate = rockchip_pll_round_rate,
+	.set_rate = rockchip_rk3399_pll_set_rate,
+	.enable = rockchip_rk3399_pll_enable,
+	.disable = rockchip_rk3399_pll_disable,
+	.is_enabled = rockchip_rk3399_pll_is_enabled,
+	.init = rockchip_rk3399_pll_init,
 };
 
 /*
  * Common registering of pll clocks
  */
 
-struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
-		const char *name, const char **parent_names, u8 num_parents,
-		void __iomem *base, int con_offset, int grf_lock_offset,
+struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+		enum rockchip_pll_type pll_type,
+		const char *name, const char *const *parent_names,
+		u8 num_parents, int con_offset, int grf_lock_offset,
 		int lock_shift, int mode_offset, int mode_shift,
 		struct rockchip_pll_rate_table *rate_table,
-		u8 clk_pll_flags)
+		unsigned long flags, u8 clk_pll_flags)
 {
-	const char **pll_parents;
+	const char *pll_parents[3];
+	struct clk_init_data init;
 	struct rockchip_clk_pll *pll;
-	struct clk *pll_mux;
-	struct clk *mux_clk;
-	int ret;
+	struct clk_mux *pll_mux;
+	struct clk *pll_clk, *mux_clk;
+	char pll_name[20];
 
-	if (num_parents != 2) {
+	if ((pll_type != pll_rk3328 && num_parents != 2) ||
+	    (pll_type == pll_rk3328 && num_parents != 1)) {
 		pr_err("%s: needs two parent clocks\n", __func__);
 		return ERR_PTR(-EINVAL);
 	}
 
+	/* name the actual pll */
+	snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
+
 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 	if (!pll)
 		return ERR_PTR(-ENOMEM);
 
-	pll_parents = kzalloc(sizeof(char *)*3, GFP_KERNEL);
-	if (!pll_parents)
-		return ERR_PTR(-ENOMEM);
+	/* create the mux on top of the real pll */
+	pll->pll_mux_ops = &clk_mux_ops;
+	pll_mux = &pll->pll_mux;
+	pll_mux->reg = ctx->reg_base + mode_offset;
+	pll_mux->shift = mode_shift;
+	if (pll_type == pll_rk3328)
+		pll_mux->width = PLL_RK3328_MODE_WIDTH;
+	else
+		pll_mux->width = PLL_MODE_WIDTH;
+	pll_mux->flags = 0;
+	pll_mux->lock = &ctx->lock;
+	pll_mux->hw.init = &init;
+
+	if (pll_type == pll_rk3036 ||
+	    pll_type == pll_rk3066 ||
+	    pll_type == pll_rk3328 ||
+	    pll_type == pll_rk3399)
+		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
 
-	/* name the actual pll */
-	snprintf(pll->pll_name, sizeof(pll->pll_name), "pll_%s", name);
-	pll->hw.clk.name = pll->pll_name;
+	/* the actual muxing is xin24m, pll-output, xin32k */
+	pll_parents[0] = parent_names[0];
+	pll_parents[1] = pll_name;
+	pll_parents[2] = parent_names[1];
 
-	pll->hw.clk.parent_names = &parent_names[0];
-	pll->hw.clk.num_parents = 1;
+	init.name = name;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.ops = pll->pll_mux_ops;
+	init.parent_names = pll_parents;
+	if (pll_type == pll_rk3328)
+		init.num_parents = 2;
+	else
+		init.num_parents = ARRAY_SIZE(pll_parents);
+
+	mux_clk = clk_register(NULL, &pll_mux->hw);
+	if (IS_ERR(mux_clk))
+		goto err_mux;
+
+	/* now create the actual pll */
+	init.name = pll_name;
+
+	/* keep all plls untouched for now */
+	init.flags = flags | CLK_IGNORE_UNUSED;
+
+	init.parent_names = &parent_names[0];
+	init.num_parents = 1;
 
 	if (rate_table) {
 		int len;
@@ -303,61 +927,62 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 			len++;
 
 		pll->rate_count = len;
-		pll->rate_table = xmemdup(rate_table,
+		pll->rate_table = kmemdup(rate_table,
 					pll->rate_count *
-					sizeof(struct rockchip_pll_rate_table)
-					);
+					sizeof(struct rockchip_pll_rate_table),
+					GFP_KERNEL);
 		WARN(!pll->rate_table,
 			"%s: could not allocate rate table for %s\n",
 			__func__, name);
 	}
 
 	switch (pll_type) {
+	case pll_rk3036:
+	case pll_rk3328:
+		if (!pll->rate_table || IS_ERR(ctx->grf))
+			init.ops = &rockchip_rk3036_pll_clk_norate_ops;
+		else
+			init.ops = &rockchip_rk3036_pll_clk_ops;
+		break;
 	case pll_rk3066:
+		if (!pll->rate_table || IS_ERR(ctx->grf))
+			init.ops = &rockchip_rk3066_pll_clk_norate_ops;
+		else
+			init.ops = &rockchip_rk3066_pll_clk_ops;
+		break;
+	case pll_rk3399:
 		if (!pll->rate_table)
-			pll->hw.clk.ops = &rockchip_rk3066_pll_clk_norate_ops;
+			init.ops = &rockchip_rk3399_pll_clk_norate_ops;
 		else
-			pll->hw.clk.ops = &rockchip_rk3066_pll_clk_ops;
+			init.ops = &rockchip_rk3399_pll_clk_ops;
 		break;
 	default:
 		pr_warn("%s: Unknown pll type for pll clk %s\n",
 			__func__, name);
 	}
 
+	pll->hw.init = &init;
 	pll->type = pll_type;
-	pll->reg_base = base + con_offset;
+	pll->reg_base = ctx->reg_base + con_offset;
 	pll->lock_offset = grf_lock_offset;
 	pll->lock_shift = lock_shift;
 	pll->flags = clk_pll_flags;
-
-	ret = bclk_register(&pll->hw.clk);
-	if (ret) {
-		pr_err("%s: failed to register pll clock %s : %d\n",
-			__func__, name, ret);
-		mux_clk = &pll->hw.clk;
-		goto err_exit;
+	pll->lock = &ctx->lock;
+	pll->ctx = ctx;
+
+	pll_clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(pll_clk)) {
+		pr_err("%s: failed to register pll clock %s : %ld\n",
+			__func__, name, PTR_ERR(pll_clk));
+		goto err_pll;
 	}
 
-	/* the actual muxing is xin24m, pll-output, xin32k */
-	pll_parents[0] = parent_names[0];
-	pll_parents[1] = pll->pll_name;
-	pll_parents[2] = parent_names[1];
-
-	pll_mux = clk_mux_alloc(name, CLK_SET_RATE_PARENT, base + mode_offset, mode_shift,
-				PLL_MODE_MASK, pll_parents, 3, 0);
-	pll->pll_mux_ops = pll_mux->ops;
-	mux_clk = pll_mux;
-
-	if (pll_type == pll_rk3066)
-		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
-
-	ret = bclk_register(pll_mux);
-	if (ret)
-		goto err_exit;
-
 	return mux_clk;
 
-err_exit:
+err_pll:
+	clk_unregister(mux_clk);
+	mux_clk = pll_clk;
+err_mux:
 	kfree(pll);
 	return mux_clk;
 }
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 61dfb27ef4..8597a9d229 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -20,7 +20,7 @@ enum rk3188_plls {
 	apll, cpll, dpll, gpll,
 };
 
-struct rockchip_pll_rate_table rk3188_pll_rates[] = {
+static struct rockchip_pll_rate_table rk3188_pll_rates[] = {
 	RK3066_PLL_RATE(2208000000, 1, 92, 1),
 	RK3066_PLL_RATE(2184000000, 1, 91, 1),
 	RK3066_PLL_RATE(2160000000, 1, 90, 1),
@@ -82,6 +82,7 @@ struct rockchip_pll_rate_table rk3188_pll_rates[] = {
 	RK3066_PLL_RATE( 504000000, 1, 84, 4),
 	RK3066_PLL_RATE( 456000000, 1, 76, 4),
 	RK3066_PLL_RATE( 408000000, 1, 68, 4),
+	RK3066_PLL_RATE( 400000000, 3, 100, 2),
 	RK3066_PLL_RATE( 384000000, 2, 128, 4),
 	RK3066_PLL_RATE( 360000000, 1, 60, 4),
 	RK3066_PLL_RATE( 312000000, 1, 52, 4),
@@ -145,10 +146,14 @@ static struct rockchip_cpuclk_rate_table rk3066_cpuclk_rates[] __initdata = {
 };
 
 static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = {
-	.core_reg = RK2928_CLKSEL_CON(0),
-	.div_core_shift = 0,
-	.div_core_mask = 0x1f,
+	.core_reg[0] = RK2928_CLKSEL_CON(0),
+	.div_core_shift[0] = 0,
+	.div_core_mask[0] = 0x1f,
+	.num_cores = 1,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
 	.mux_core_shift = 8,
+	.mux_core_mask = 0x1,
 };
 
 #define RK3188_DIV_ACLK_CORE_MASK	0x7
@@ -181,10 +186,14 @@ static struct rockchip_cpuclk_rate_table rk3188_cpuclk_rates[] __initdata = {
 };
 
 static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = {
-	.core_reg = RK2928_CLKSEL_CON(0),
-	.div_core_shift = 9,
-	.div_core_mask = 0x1f,
+	.core_reg[0] = RK2928_CLKSEL_CON(0),
+	.div_core_shift[0] = 9,
+	.div_core_mask[0] = 0x1f,
+	.num_cores = 1,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
 	.mux_core_shift = 8,
+	.mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)		= { "xin24m", "xin32k" };
@@ -195,7 +204,7 @@ PNAME(mux_pll_src_cpll_gpll_p)	= { "cpll", "gpll" };
 PNAME(mux_aclk_cpu_p)		= { "apll", "gpll" };
 PNAME(mux_sclk_cif0_p)		= { "cif0_pre", "xin24m" };
 PNAME(mux_sclk_i2s0_p)		= { "i2s0_pre", "i2s0_frac", "xin12m" };
-PNAME(mux_sclk_spdif_p)		= { "spdif_src", "spdif_frac", "xin12m" };
+PNAME(mux_sclk_spdif_p)		= { "spdif_pre", "spdif_frac", "xin12m" };
 PNAME(mux_sclk_uart0_p)		= { "uart0_pre", "uart0_frac", "xin24m" };
 PNAME(mux_sclk_uart1_p)		= { "uart1_pre", "uart1_frac", "xin24m" };
 PNAME(mux_sclk_uart2_p)		= { "uart2_pre", "uart2_frac", "xin24m" };
@@ -229,6 +238,7 @@ static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
 #define MFLAGS CLK_MUX_HIWORD_MASK
 #define DFLAGS CLK_DIVIDER_HIWORD_MASK
 #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK
 
 /* 2 ^ (val + 1) */
 static struct clk_div_table div_core_peri_t[] = {
@@ -239,6 +249,30 @@ static struct clk_div_table div_core_peri_t[] = {
 	{ /* sentinel */ },
 };
 
+static struct rockchip_clk_branch common_hsadc_out_fracmux __initdata =
+	MUX(0, "sclk_hsadc_out", mux_sclk_hsadc_p, 0,
+			RK2928_CLKSEL_CON(22), 4, 2, MFLAGS);
+
+static struct rockchip_clk_branch common_spdif_fracmux __initdata =
+	MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(5), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch common_uart0_fracmux __initdata =
+	MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(13), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch common_uart1_fracmux __initdata =
+	MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(14), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch common_uart2_fracmux __initdata =
+	MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch common_uart3_fracmux __initdata =
+	MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(16), 8, 2, MFLAGS);
+
 static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	/*
 	 * Clock-Architecture Diagram 2
@@ -251,15 +285,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 			RK2928_CLKSEL_CON(0), 6, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
 			div_core_peri_t, RK2928_CLKGATE_CON(0), 0, GFLAGS),
 
-	COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0,
+	COMPOSITE(ACLK_VEPU, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0,
 			RK2928_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 5, DFLAGS,
 			RK2928_CLKGATE_CON(3), 9, GFLAGS),
-	GATE(0, "hclk_vepu", "aclk_vepu", 0,
+	GATE(HCLK_VEPU, "hclk_vepu", "aclk_vepu", 0,
 			RK2928_CLKGATE_CON(3), 10, GFLAGS),
-	COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0,
+	COMPOSITE(ACLK_VDPU, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0,
 			RK2928_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS,
 			RK2928_CLKGATE_CON(3), 11, GFLAGS),
-	GATE(0, "hclk_vdpu", "aclk_vdpu", 0,
+	GATE(HCLK_VDPU, "hclk_vdpu", "aclk_vdpu", 0,
 			RK2928_CLKGATE_CON(3), 12, GFLAGS),
 
 	GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
@@ -268,14 +302,14 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 			RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
 			RK2928_CLKGATE_CON(0), 2, GFLAGS),
 
-	GATE(0, "aclk_cpu", "aclk_cpu_pre", 0,
+	GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0,
 			RK2928_CLKGATE_CON(0), 3, GFLAGS),
 
 	GATE(0, "atclk_cpu", "pclk_cpu_pre", 0,
 			RK2928_CLKGATE_CON(0), 6, GFLAGS),
-	GATE(0, "pclk_cpu", "pclk_cpu_pre", 0,
+	GATE(PCLK_CPU, "pclk_cpu", "pclk_cpu_pre", 0,
 			RK2928_CLKGATE_CON(0), 5, GFLAGS),
-	GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED,
+	GATE(HCLK_CPU, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED,
 			RK2928_CLKGATE_CON(0), 4, GFLAGS),
 
 	COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
@@ -285,12 +319,12 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 			RK2928_CLKSEL_CON(31), 15, 1, MFLAGS, 8, 5, DFLAGS,
 			RK2928_CLKGATE_CON(1), 4, GFLAGS),
 
-	GATE(0, "aclk_peri", "aclk_peri_pre", 0,
+	GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0,
 			RK2928_CLKGATE_CON(2), 1, GFLAGS),
-	COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_pre", 0,
+	COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre", 0,
 			RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
 			RK2928_CLKGATE_CON(2), 2, GFLAGS),
-	COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_pre", 0,
+	COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_pre", 0,
 			RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
 			RK2928_CLKGATE_CON(2), 3, GFLAGS),
 
@@ -304,14 +338,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif0", "ext_cif0", 0,
 			RK2928_CLKGATE_CON(3), 3, GFLAGS),
+	INVERTER(0, "pclk_cif0", "pclkin_cif0",
+			RK2928_CLKSEL_CON(30), 8, IFLAGS),
+
+	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
 
 	/*
 	 * the 480m are generated inside the usb block from these clocks,
 	 * but they are also a source for the hsicphy clock.
 	 */
-	GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
+	GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED,
 			RK2928_CLKGATE_CON(1), 5, GFLAGS),
-	GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
+	GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED,
 			RK2928_CLKGATE_CON(1), 6, GFLAGS),
 
 	COMPOSITE(0, "mac_src", mux_mac_p, 0,
@@ -319,17 +357,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 			RK2928_CLKGATE_CON(2), 5, GFLAGS),
 	MUX(SCLK_MAC, "sclk_macref", mux_sclk_macref_p, CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(21), 4, 1, MFLAGS),
-	GATE(0, "sclk_mac_lbtest", "sclk_macref",
-			RK2928_CLKGATE_CON(2), 12, 0, GFLAGS),
+	GATE(0, "sclk_mac_lbtest", "sclk_macref", 0,
+			RK2928_CLKGATE_CON(2), 12, GFLAGS),
 
 	COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0,
 			RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
 			RK2928_CLKGATE_CON(2), 6, GFLAGS),
-	COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0,
+	COMPOSITE_FRACMUX(0, "hsadc_frac", "hsadc_src", 0,
 			RK2928_CLKSEL_CON(23), 0,
-			RK2928_CLKGATE_CON(2), 7, GFLAGS),
-	MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0,
-			RK2928_CLKSEL_CON(22), 4, 2, MFLAGS),
+			RK2928_CLKGATE_CON(2), 7, GFLAGS,
+			&common_hsadc_out_fracmux),
+	INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
+			RK2928_CLKSEL_CON(22), 7, IFLAGS),
 
 	COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0,
 			RK2928_CLKSEL_CON(24), 8, 8, DFLAGS,
@@ -338,18 +377,17 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 13, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
+	COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(9), 0,
-			RK2928_CLKGATE_CON(0), 14, GFLAGS),
-	MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
-			RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 14, GFLAGS,
+			&common_spdif_fracmux),
 
 	/*
 	 * Clock-Architecture Diagram 4
 	 */
 
-	GATE(SCLK_SMC, "sclk_smc", "hclk_peri",
-			RK2928_CLKGATE_CON(2), 4, 0, GFLAGS),
+	GATE(SCLK_SMC, "sclk_smc", "hclk_peri", 0,
+			RK2928_CLKGATE_CON(2), 4, GFLAGS),
 
 	COMPOSITE_NOMUX(SCLK_SPI0, "sclk_spi0", "pclk_peri", 0,
 			RK2928_CLKSEL_CON(25), 0, 7, DFLAGS,
@@ -373,35 +411,31 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 8, GFLAGS),
-	COMPOSITE_FRAC(0, "uart0_frac", "uart0_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(17), 0,
-			RK2928_CLKGATE_CON(1), 9, GFLAGS),
-	MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0,
-			RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 9, GFLAGS,
+			&common_uart0_fracmux),
 	COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 10, GFLAGS),
-	COMPOSITE_FRAC(0, "uart1_frac", "uart1_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(18), 0,
-			RK2928_CLKGATE_CON(1), 11, GFLAGS),
-	MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0,
-			RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 11, GFLAGS,
+			&common_uart1_fracmux),
 	COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart2_frac", "uart2_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(19), 0,
-			RK2928_CLKGATE_CON(1), 13, GFLAGS),
-	MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0,
-			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 13, GFLAGS,
+			&common_uart2_fracmux),
 	COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 14, GFLAGS),
-	COMPOSITE_FRAC(0, "uart3_frac", "uart3_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(20), 0,
-			RK2928_CLKGATE_CON(1), 15, GFLAGS),
-	MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0,
-			RK2928_CLKSEL_CON(16), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 15, GFLAGS,
+			&common_uart3_fracmux),
 
 	GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS),
 
@@ -418,7 +452,6 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
 	/* hclk_cpu gates */
 	GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS),
-	GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
 	GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS),
 	GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS),
 	/* hclk_ahb2apb is part of a clk branch */
@@ -468,8 +501,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
 	GATE(PCLK_EFUSE, "pclk_efuse", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS),
 	GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 3, GFLAGS),
-	GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
-	GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
+	GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(PCLK_PUBL, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
 	GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
 	GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
 	GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS),
@@ -511,6 +544,18 @@ static struct clk_div_table div_aclk_cpu_t[] = {
 	{ /* sentinel */ },
 };
 
+static struct rockchip_clk_branch rk3066a_i2s0_fracmux __initdata =
+	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(2), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3066a_i2s1_fracmux __initdata =
+	MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3066a_i2s2_fracmux __initdata =
+	MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(4), 8, 2, MFLAGS);
+
 static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 	DIVTBL(0, "aclk_cpu_pre", "armclk", 0,
 			RK2928_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, div_aclk_cpu_t),
@@ -535,12 +580,12 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 	COMPOSITE(0, "dclk_lcdc0_src", mux_pll_src_cpll_gpll_p, 0,
 			RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS,
 			RK2928_CLKGATE_CON(3), 1, GFLAGS),
-	MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, 0,
+	MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(27), 4, 1, MFLAGS),
 	COMPOSITE(0, "dclk_lcdc1_src", mux_pll_src_cpll_gpll_p, 0,
 			RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS,
 			RK2928_CLKGATE_CON(3), 2, GFLAGS),
-	MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, 0,
+	MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(28), 4, 1, MFLAGS),
 
 	COMPOSITE_NOMUX(0, "cif1_pre", "cif_src", 0,
@@ -551,6 +596,8 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif1", "ext_cif1", 0,
 			RK2928_CLKGATE_CON(3), 4, GFLAGS),
+	INVERTER(0, "pclk_cif1", "pclkin_cif1",
+			RK2928_CLKSEL_CON(30), 12, IFLAGS),
 
 	COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
 			RK2928_CLKSEL_CON(33), 8, 1, MFLAGS, 0, 5, DFLAGS,
@@ -561,7 +608,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 	GATE(SCLK_TIMER2, "timer2", "xin24m", 0,
 			RK2928_CLKGATE_CON(3), 2, GFLAGS),
 
-	COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0,
+	COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0,
 			RK2928_CLKSEL_CON(34), 0, 16, DFLAGS,
 			RK2928_CLKGATE_CON(2), 15, GFLAGS),
 
@@ -570,37 +617,35 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(2), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 7, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(6), 0,
-			RK2928_CLKGATE_CON(0), 8, GFLAGS),
-	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
-			RK2928_CLKSEL_CON(2), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 8, GFLAGS,
+			&rk3066a_i2s0_fracmux),
 	COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 9, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(7), 0,
-			RK2928_CLKGATE_CON(0), 10, GFLAGS),
-	MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0,
-			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 10, GFLAGS,
+			&rk3066a_i2s1_fracmux),
 	COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(4), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 11, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(8), 0,
-			RK2928_CLKGATE_CON(0), 12, GFLAGS),
-	MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0,
-			RK2928_CLKSEL_CON(4), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 12, GFLAGS,
+			&rk3066a_i2s2_fracmux),
 
-	GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
-	GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
-	GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
-	GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
+	GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
+	GATE(HCLK_HDMI, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 
 	GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
 			RK2928_CLKGATE_CON(5), 14, GFLAGS),
 
-	GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
+	GATE(ACLK_CIF1, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
 
 	GATE(PCLK_TIMER1, "pclk_timer1", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 8, GFLAGS),
 	GATE(PCLK_TIMER2, "pclk_timer2", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
@@ -621,9 +666,13 @@ static struct clk_div_table div_rk3188_aclk_core_t[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(mux_hsicphy_p)		= { "sclk_otgphy0", "sclk_otgphy1",
+PNAME(mux_hsicphy_p)		= { "sclk_otgphy0_480m", "sclk_otgphy1_480m",
 				    "gpll", "cpll" };
 
+static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata =
+	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS);
+
 static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
 			RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
@@ -677,12 +726,12 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 9, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(7), 0,
-			RK2928_CLKGATE_CON(0), 10, GFLAGS),
-	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
-			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 10, GFLAGS,
+			&rk3188_i2s0_fracmux),
 
+	GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
 	GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 	GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
 
@@ -698,142 +747,104 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
 	GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
 };
 
-static const char *rk3188_critical_clocks[] __initconst = {
+static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
 	"hclk_peri",
+	"pclk_cpu",
+	"pclk_peri",
+	"hclk_cpubus",
+	"hclk_vio_bus",
+	"sclk_mac_lbtest",
 };
 
-
-static void __init rockchip_reparent_clk(char *clock, char *new_parent)
-{
-	struct clk *clk1, *clk2;
-	unsigned long rate;
-	int ret;
-
-	clk1 = __clk_lookup(clock);
-	clk2 = __clk_lookup(new_parent);
-	if (!IS_ERR(clk1) && !IS_ERR(clk2)) {
-		rate = clk_get_rate(clk1);
-
-		ret = clk_set_parent(clk1, clk2);
-		if (ret < 0)
-			pr_err("%s: could not reparent %s to %s, ret=%d\n",
-				__func__, clock, new_parent, ret);
-
-		clk_set_rate(clk1, rate);
-	} else {
-		pr_err("%s: missing clocks to reparent %s to %s\n",
-			__func__, clock, new_parent);
-	}
-}
-
-static void __init rockchip_clk_set_rate(char *clock, unsigned long rate)
-{
-	struct clk *clk;
-
-	clk = __clk_lookup(clock);
-	if(clk && !IS_ERR(clk)) {
-		clk_set_rate(clk, rate);
-		return;
-	}
-	pr_err("%s: missing clock %s when setting initial rate to %lu\n",
-		__func__, clock, rate);
-}
-
-static void __init rockchip_clk_set_defaults(void)
-{
-	struct rockchip_initial_rate {
-		char *name;
-		unsigned long rate;
-	};
-	int i;
-
-	struct rockchip_initial_rate rates[] = {
-		{"gpll", 891000000},
-		{"cpll", 600000000},
-		{"aclk_cpu", 300000000},
-		{"hclk_cpu", 150000000},
-		{"pclk_cpu", 75000000},
-		{"hclk_ahb2apb", 75000000},
-		{"aclk_peri_pre", 150000000},
-		{"hclk_peri", 150000000},
-		{"pclk_peri", 75000000},
-	};
-
-	rockchip_reparent_clk("aclk_cpu_pre", "gpll");
-	rockchip_reparent_clk("mac_src", "dpll");
-	rockchip_reparent_clk("aclk_peri_pre", "cpll");
-
-	for(i = 0; i < ARRAY_SIZE(rates); i++)
-		rockchip_clk_set_rate(rates[i].name, rates[i].rate);
-}
-
-static void __init rk3188_common_clk_init(struct device_node *np)
+static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
 {
+	struct rockchip_clk_provider *ctx;
 	void __iomem *reg_base;
-	struct clk *clk;
 
 	reg_base = of_iomap(np, 0);
 	if (!reg_base) {
 		pr_err("%s: could not map cru region\n", __func__);
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
 
-	rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
-
-	/* Fixed-clock should be registered before all others */
-	clk=clk_fixed("xin24m",24000000);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock xin24m: %ld\n",
-			__func__, PTR_ERR(clk));
-
-	/* xin12m is created by an cru-internal divider */
-	clk = clk_fixed_factor("xin12m", "xin24m", 1, 2, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock xin12m: %ld\n",
-			__func__, PTR_ERR(clk));
-
-	clk = clk_fixed_factor("usb480m", "xin24m", 20, 1, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock usb480m: %ld\n",
-			__func__, PTR_ERR(clk));
+	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
 
-	rockchip_clk_register_branches(common_clk_branches,
+	rockchip_clk_register_branches(ctx, common_clk_branches,
 				  ARRAY_SIZE(common_clk_branches));
-	rockchip_clk_protect_critical(rk3188_critical_clocks,
-				      ARRAY_SIZE(rk3188_critical_clocks));
+
+	return ctx;
 }
 
 static void __init rk3066a_clk_init(struct device_node *np)
 {
-	rk3188_common_clk_init(np);
-	rockchip_clk_register_plls(rk3066_pll_clks,
+	struct rockchip_clk_provider *ctx;
+
+	ctx = rk3188_common_clk_init(np);
+	if (IS_ERR(ctx))
+		return;
+
+	rockchip_clk_register_plls(ctx, rk3066_pll_clks,
 				   ARRAY_SIZE(rk3066_pll_clks),
 				   RK3066_GRF_SOC_STATUS);
-	rockchip_clk_register_branches(rk3066a_clk_branches,
+	rockchip_clk_register_branches(ctx, rk3066a_clk_branches,
 				  ARRAY_SIZE(rk3066a_clk_branches));
-	rockchip_clk_register_armclk(ARMCLK, "armclk",
+	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
 			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
 			&rk3066_cpuclk_data, rk3066_cpuclk_rates,
 			ARRAY_SIZE(rk3066_cpuclk_rates));
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
+	rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
 
 static void __init rk3188a_clk_init(struct device_node *np)
 {
-	rk3188_common_clk_init(np);
-	rockchip_clk_register_plls(rk3188_pll_clks,
+	struct rockchip_clk_provider *ctx;
+	struct clk *clk1, *clk2;
+	unsigned long rate;
+	int ret;
+
+	ctx = rk3188_common_clk_init(np);
+	if (IS_ERR(ctx))
+		return;
+
+	rockchip_clk_register_plls(ctx, rk3188_pll_clks,
 				   ARRAY_SIZE(rk3188_pll_clks),
 				   RK3188_GRF_SOC_STATUS);
-	rockchip_clk_register_branches(rk3188_clk_branches,
+	rockchip_clk_register_branches(ctx, rk3188_clk_branches,
 				  ARRAY_SIZE(rk3188_clk_branches));
-	rockchip_clk_register_armclk(ARMCLK, "armclk",
+	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
 				  mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
 				  &rk3188_cpuclk_data, rk3188_cpuclk_rates,
 				  ARRAY_SIZE(rk3188_cpuclk_rates));
 
-	rockchip_clk_set_defaults();
+	/* reparent aclk_cpu_pre from apll */
+	clk1 = __clk_lookup("aclk_cpu_pre");
+	clk2 = __clk_lookup("gpll");
+	if (clk1 && clk2) {
+		rate = clk_get_rate(clk1);
+
+		ret = clk_set_parent(clk1, clk2);
+		if (ret < 0)
+			pr_warn("%s: could not reparent aclk_cpu_pre to gpll\n",
+				__func__);
+
+		clk_set_rate(clk1, rate);
+	} else {
+		pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n",
+			__func__);
+	}
+
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
+	rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
 
@@ -850,7 +861,7 @@ static void __init rk3188_clk_init(struct device_node *np)
 
 		rate = pll->rate_table;
 		while (rate->rate > 0) {
-			rate->bwadj = 0;
+			rate->nb = 1;
 			rate++;
 		}
 	}
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index b6c122d393..fc9554e0f3 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -16,6 +16,11 @@
 #define RK3288_GRF_SOC_CON(x)	(0x244 + x * 4)
 #define RK3288_GRF_SOC_STATUS1	0x284
 
+enum rk3288_variant {
+	RK3288_CRU,
+	RK3288W_CRU,
+};
+
 enum rk3288_plls {
 	apll, dpll, cpll, gpll, npll,
 };
@@ -76,24 +81,44 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
 	RK3066_PLL_RATE( 768000000, 1, 64, 2),
 	RK3066_PLL_RATE( 742500000, 8, 495, 2),
 	RK3066_PLL_RATE( 696000000, 1, 58, 2),
+	RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1),
 	RK3066_PLL_RATE( 600000000, 1, 50, 2),
-	RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1),
+	RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1),
 	RK3066_PLL_RATE( 552000000, 1, 46, 2),
 	RK3066_PLL_RATE( 504000000, 1, 84, 4),
 	RK3066_PLL_RATE( 500000000, 3, 125, 2),
 	RK3066_PLL_RATE( 456000000, 1, 76, 4),
+	RK3066_PLL_RATE( 428000000, 1, 107, 6),
 	RK3066_PLL_RATE( 408000000, 1, 68, 4),
 	RK3066_PLL_RATE( 400000000, 3, 100, 2),
+	RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1),
 	RK3066_PLL_RATE( 384000000, 2, 128, 4),
 	RK3066_PLL_RATE( 360000000, 1, 60, 4),
+	RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1),
+	RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1),
 	RK3066_PLL_RATE( 312000000, 1, 52, 4),
-	RK3066_PLL_RATE( 300000000, 1, 50, 4),
-	RK3066_PLL_RATE( 297000000, 2, 198, 8),
+	RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1),
+	RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1),
+	RK3066_PLL_RATE( 300000000, 1, 75, 6),
+	RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1),
+	RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1),
+	RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1),
+	RK3066_PLL_RATE( 273600000, 1, 114, 10),
+	RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1),
+	RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1),
+	RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1),
+	RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1),
 	RK3066_PLL_RATE( 252000000, 1, 84, 8),
-	RK3066_PLL_RATE( 216000000, 1, 72, 8),
-	RK3066_PLL_RATE( 148500000, 2, 99, 8),
+	RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1),
+	RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1),
+	RK3066_PLL_RATE( 238000000, 1, 119, 12),
+	RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1),
+	RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1),
+	RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1),
+	RK3066_PLL_RATE( 195428571, 1, 114, 14),
+	RK3066_PLL_RATE( 160000000, 1, 80, 12),
+	RK3066_PLL_RATE( 157500000, 1, 105, 16),
 	RK3066_PLL_RATE( 126000000, 1, 84, 16),
-	RK3066_PLL_RATE(  48000000, 1, 64, 32),
 	{ /* sentinel */ },
 };
 
@@ -155,10 +180,14 @@ static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
 };
 
 static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
-	.core_reg = RK3288_CLKSEL_CON(0),
-	.div_core_shift = 8,
-	.div_core_mask = 0x1f,
+	.core_reg[0] = RK3288_CLKSEL_CON(0),
+	.div_core_shift[0] = 8,
+	.div_core_mask[0] = 0x1f,
+	.num_cores = 1,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
 	.mux_core_shift = 15,
+	.mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)		= { "xin24m", "xin32k" };
@@ -169,8 +198,8 @@ PNAME(mux_aclk_cpu_src_p)	= { "cpll_aclk_cpu", "gpll_aclk_cpu" };
 PNAME(mux_pll_src_cpll_gpll_p)		= { "cpll", "gpll" };
 PNAME(mux_pll_src_npll_cpll_gpll_p)	= { "npll", "cpll", "gpll" };
 PNAME(mux_pll_src_cpll_gpll_npll_p)	= { "cpll", "gpll", "npll" };
-PNAME(mux_pll_src_cpll_gpll_usb480m_p)	= { "cpll", "gpll", "usbphy480m_src" };
-PNAME(mux_pll_src_cpll_gll_usb_npll_p)	= { "cpll", "gpll", "usbphy480m_src", "npll" };
+PNAME(mux_pll_src_cpll_gpll_usb480m_p)	= { "cpll", "gpll", "unstable:usbphy480m_src" };
+PNAME(mux_pll_src_cpll_gll_usb_npll_p)	= { "cpll", "gpll", "unstable:usbphy480m_src", "npll" };
 
 PNAME(mux_mmc_src_p)	= { "cpll", "gpll", "xin24m", "xin24m" };
 PNAME(mux_i2s_pre_p)	= { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
@@ -188,8 +217,9 @@ PNAME(mux_hsadcout_p)	= { "hsadc_src", "ext_hsadc" };
 PNAME(mux_edp_24m_p)	= { "ext_edp_24m", "xin24m" };
 PNAME(mux_tspout_p)	= { "cpll", "gpll", "npll", "xin27m" };
 
-PNAME(mux_usbphy480m_p)		= { "sclk_otgphy1", "sclk_otgphy2",
-				    "sclk_otgphy0" };
+PNAME(mux_aclk_vcodec_pre_p)	= { "aclk_vdpu", "aclk_vepu" };
+PNAME(mux_usbphy480m_p)		= { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
+				    "sclk_otgphy0_480m" };
 PNAME(mux_hsicphy480m_p)	= { "cpll", "gpll", "usbphy480m_src" };
 PNAME(mux_hsicphy12m_p)		= { "hsicphy12m_xin12m", "hsicphy12m_usbphy" };
 
@@ -216,6 +246,39 @@ static struct clk_div_table div_hclk_cpu_t[] = {
 #define MFLAGS CLK_MUX_HIWORD_MASK
 #define DFLAGS CLK_DIVIDER_HIWORD_MASK
 #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK
+
+static struct rockchip_clk_branch rk3288_i2s_fracmux __initdata =
+	MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(4), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_spdif_fracmux __initdata =
+	MUX(0, "spdif_mux", mux_spdif_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(5), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_spdif_8ch_fracmux __initdata =
+	MUX(0, "spdif_8ch_mux", mux_spdif_8ch_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(40), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_uart0_fracmux __initdata =
+	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(13), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_uart1_fracmux __initdata =
+	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(14), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_uart2_fracmux __initdata =
+	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(15), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_uart3_fracmux __initdata =
+	MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(16), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3288_uart4_fracmux __initdata =
+	MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
+			RK3288_CLKSEL_CON(3), 8, 2, MFLAGS);
 
 static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	/*
@@ -287,20 +350,21 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 			RK3288_CLKGATE_CON(0), 4, GFLAGS),
 	GATE(0, "c2c_host", "aclk_cpu_src", 0,
 			RK3288_CLKGATE_CON(13), 8, GFLAGS),
-	COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0,
+	COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0,
 			RK3288_CLKSEL_CON(26), 6, 2, DFLAGS,
 			RK3288_CLKGATE_CON(5), 4, GFLAGS),
 	GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
 			RK3288_CLKGATE_CON(0), 7, GFLAGS),
 
+	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+
 	COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 1, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(8), 0,
-			RK3288_CLKGATE_CON(4), 2, GFLAGS),
-	MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(4), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(4), 2, GFLAGS,
+			&rk3288_i2s_fracmux),
 	COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0,
 			RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
 			RK3288_CLKGATE_CON(4), 0, GFLAGS),
@@ -309,27 +373,28 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 
 	MUX(0, "spdif_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(5), 15, 1, MFLAGS),
-	COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", 0,
+	COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(5), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 4, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
+	COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(9), 0,
-			RK3288_CLKGATE_CON(4), 5, GFLAGS),
-	COMPOSITE_NODIV(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
-			RK3288_CLKSEL_CON(5), 8, 2, MFLAGS,
+			RK3288_CLKGATE_CON(4), 5, GFLAGS,
+			&rk3288_spdif_fracmux),
+	GATE(SCLK_SPDIF, "sclk_spdif", "spdif_mux", CLK_SET_RATE_PARENT,
 			RK3288_CLKGATE_CON(4), 6, GFLAGS),
-	COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0,
+	COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(40), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 7, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0,
+	COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_pre", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(41), 0,
-			RK3288_CLKGATE_CON(4), 8, GFLAGS),
-	COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0,
-			RK3288_CLKSEL_CON(40), 8, 2, MFLAGS,
+			RK3288_CLKGATE_CON(4), 8, GFLAGS,
+			&rk3288_spdif_8ch_fracmux),
+	GATE(SCLK_SPDIF8CH, "sclk_spdif_8ch", "spdif_8ch_mux", CLK_SET_RATE_PARENT,
 			RK3288_CLKGATE_CON(4), 9, GFLAGS),
 
 	GATE(0, "sclk_acc_efuse", "xin24m", 0,
 			RK3288_CLKGATE_CON(0), 12, GFLAGS),
+
 	GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
 			RK3288_CLKGATE_CON(1), 0, GFLAGS),
 	GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
@@ -342,6 +407,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 			RK3288_CLKGATE_CON(1), 4, GFLAGS),
 	GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
 			RK3288_CLKGATE_CON(1), 5, GFLAGS),
+
 	/*
 	 * Clock-Architecture Diagram 2
 	 */
@@ -352,26 +418,20 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
 			RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
 			RK3288_CLKGATE_CON(3), 11, GFLAGS),
-	/*
-	 * We use aclk_vdpu by default GRF_SOC_CON0[7] setting in system,
-	 * so we ignore the mux and make clocks nodes as following,
-	 */
-	GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0,
+	MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
+			RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
+	GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
 		RK3288_CLKGATE_CON(9), 0, GFLAGS),
-	/*
-	 * We introduce a virtul node of hclk_vodec_pre_v to split one clock
-	 * struct with a gate and a fix divider into two node in software.
-	 */
-	GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0,
+
+	FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0, 1, 4,
 		RK3288_CLKGATE_CON(3), 10, GFLAGS),
+
 	GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
 		RK3288_CLKGATE_CON(9), 1, GFLAGS),
 
 	COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
 			RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
 			RK3288_CLKGATE_CON(3), 0, GFLAGS),
-	DIV(0, "hclk_vio", "aclk_vio0", 0,
-			RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
 	COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
 			RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
 			RK3288_CLKGATE_CON(3), 2, GFLAGS),
@@ -425,7 +485,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(26), 8, 1, MFLAGS,
 			RK3288_CLKGATE_CON(3), 7, GFLAGS),
-	COMPOSITE_NOGATE(0, "sclk_vip_out", mux_vip_out_p, 0,
+	COMPOSITE_NOGATE(SCLK_VIP_OUT, "sclk_vip_out", mux_vip_out_p, 0,
 			RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS),
 
 	DIV(0, "pclk_pd_alive", "gpll", 0,
@@ -496,11 +556,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 			RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
 			RK3288_CLKGATE_CON(4), 10, GFLAGS),
 
-	GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
+	GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED,
 			RK3288_CLKGATE_CON(13), 4, GFLAGS),
-	GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
+	GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED,
 			RK3288_CLKGATE_CON(13), 5, GFLAGS),
-	GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED,
+	GATE(SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLK_IGNORE_UNUSED,
 			RK3288_CLKGATE_CON(13), 6, GFLAGS),
 	GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED,
 			RK3288_CLKGATE_CON(13), 7, GFLAGS),
@@ -526,45 +586,40 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
 			RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 8, GFLAGS),
-	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(17), 0,
-			RK3288_CLKGATE_CON(1), 9, GFLAGS),
-	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 9, GFLAGS,
+			&rk3288_uart0_fracmux),
 	MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 10, GFLAGS),
-	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(18), 0,
-			RK3288_CLKGATE_CON(1), 11, GFLAGS),
-	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 11, GFLAGS,
+			&rk3288_uart1_fracmux),
 	COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(19), 0,
-			RK3288_CLKGATE_CON(1), 13, GFLAGS),
-	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 13, GFLAGS,
+			&rk3288_uart2_fracmux),
 	COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 14, GFLAGS),
-	COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(20), 0,
-			RK3288_CLKGATE_CON(1), 15, GFLAGS),
-	MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 15, GFLAGS,
+			&rk3288_uart3_fracmux),
 	COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(2), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(7), 0,
-			RK3288_CLKGATE_CON(2), 13, GFLAGS),
-	MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(2), 13, GFLAGS,
+			&rk3288_uart4_fracmux),
 
 	COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
@@ -585,6 +640,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 			RK3288_CLKGATE_CON(2), 6, GFLAGS),
 	MUX(0, "sclk_hsadc_out", mux_hsadcout_p, 0,
 			RK3288_CLKSEL_CON(22), 4, 1, MFLAGS),
+	INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
+			RK3288_CLKSEL_CON(22), 7, IFLAGS),
 
 	GATE(0, "jtag", "ext_jtag", 0,
 			RK3288_CLKGATE_CON(4), 14, GFLAGS),
@@ -632,11 +689,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS),
 	GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS),
 	GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS),
-	GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
+	GATE(PCLK_EFUSE1024, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
 	GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
 	GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
-	GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
-	GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS),
+	GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
+	GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
 
 	/* ddrctrl [DDR Controller PHY clock] gates */
 	GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
@@ -649,7 +706,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	/* aclk_peri gates */
 	GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS),
 	GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
-	GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS),
 	GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS),
 	GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
 	GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
@@ -697,7 +754,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
 	GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
 	GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
-	GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(SCLK_MIPIDSI_24M, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
 
 	/* sclk_gpu gates */
 	GATE(ACLK_GPU, "aclk_gpu", "sclk_gpu", 0, RK3288_CLKGATE_CON(18), 0, GFLAGS),
@@ -712,12 +769,15 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
 	GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
 	GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS),
-	GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS),
+	GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS),
+
+	/* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
+	SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_pd_alive"),
 
 	/* pclk_pd_pmu gates */
 	GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS),
 	GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS),
-	GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS),
+	GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS),
 	GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS),
 	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
 
@@ -726,7 +786,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
 	GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
 	GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS),
-	GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS),
+	GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS),
 	GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
 	GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
 	GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
@@ -742,83 +802,106 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	/* aclk_vio0 gates */
 	GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
 	GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
-	GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS),
+	GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS),
 	GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
 
 	/* aclk_vio1 gates */
 	GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
 	GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
-	GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS),
+	GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS),
 
 	/* aclk_rga_pre gates */
 	GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
-	GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS),
+	GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS),
 
 	/*
 	 * Other ungrouped clocks.
 	 */
 
 	GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS),
-	GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS),
+	INVERTER(0, "pclk_vip", "pclk_vip_in", RK3288_CLKSEL_CON(29), 4, IFLAGS),
+	GATE(PCLK_ISP_IN, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS),
+	INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS),
+};
+
+static struct rockchip_clk_branch rk3288w_hclkvio_branch[] __initdata = {
+	DIV(0, "hclk_vio", "aclk_vio1", 0,
+			RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
 };
 
-static const char *rk3288_critical_clocks[] __initconst = {
+static struct rockchip_clk_branch rk3288_hclkvio_branch[] __initdata = {
+	DIV(0, "hclk_vio", "aclk_vio0", 0,
+			RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
+};
+
+static const char *const rk3288_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
+	"aclk_peri_niu",
+	"aclk_vio0_niu",
+	"aclk_vio1_niu",
+	"aclk_rga_niu",
 	"hclk_peri",
+	"hclk_vio_niu",
+	"pclk_alive_niu",
 	"pclk_pd_pmu",
+	"pclk_pmu_niu",
+	"pmu_hclk_otg0",
+	/* pwm-regulators on some boards, so handoff-critical later */
+	"pclk_rkpwm",
 };
 
-static int __init rk3288_clk_init(struct device_node *np)
+static void __iomem *rk3288_cru_base;
+
+static void __init rk3288_common_init(struct device_node *np,
+				      enum rk3288_variant soc)
 {
-	void __iomem *reg_base;
-	struct clk *clk;
+	struct rockchip_clk_provider *ctx;
 
-	reg_base = of_iomap(np, 0);
-	if (!reg_base) {
+	rk3288_cru_base = of_iomap(np, 0);
+	if (!rk3288_cru_base) {
 		pr_err("%s: could not map cru region\n", __func__);
-		return -ENOMEM;
+		return;
 	}
 
-	rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
-
-	/* xin12m is created by an cru-internal divider */
-	clk = clk_fixed_factor("xin12m", "xin24m", 1, 2, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock xin12m: %ld\n",
-			__func__, PTR_ERR(clk));
-
-	clk = clk_fixed_factor("usb480m", "xin24m", 20, 1, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock usb480m: %ld\n",
-			__func__, PTR_ERR(clk));
-
-	clk = clk_fixed_factor("hclk_vcodec_pre",
-					"hclk_vcodec_pre_v", 1, 4, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
-			__func__, PTR_ERR(clk));
-
-	/* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
-	clk = clk_fixed_factor("pclk_wdt", "pclk_pd_alive", 1, 1, 0);
-	if (IS_ERR(clk))
-		pr_warn("%s: could not register clock pclk_wdt: %ld\n",
-			__func__, PTR_ERR(clk));
-	else
-		rockchip_clk_add_lookup(clk, PCLK_WDT);
+	ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		return;
+	}
 
-	rockchip_clk_register_plls(rk3288_pll_clks,
+	rockchip_clk_register_plls(ctx, rk3288_pll_clks,
 				   ARRAY_SIZE(rk3288_pll_clks),
 				   RK3288_GRF_SOC_STATUS1);
-	rockchip_clk_register_branches(rk3288_clk_branches,
+	rockchip_clk_register_branches(ctx, rk3288_clk_branches,
 				  ARRAY_SIZE(rk3288_clk_branches));
+
+	if (soc == RK3288W_CRU)
+		rockchip_clk_register_branches(ctx, rk3288w_hclkvio_branch,
+					       ARRAY_SIZE(rk3288w_hclkvio_branch));
+	else
+		rockchip_clk_register_branches(ctx, rk3288_hclkvio_branch,
+					       ARRAY_SIZE(rk3288_hclkvio_branch));
+
 	rockchip_clk_protect_critical(rk3288_critical_clocks,
 				      ARRAY_SIZE(rk3288_critical_clocks));
 
-	rockchip_clk_register_armclk(ARMCLK, "armclk",
+	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
 			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
 			&rk3288_cpuclk_data, rk3288_cpuclk_rates,
 			ARRAY_SIZE(rk3288_cpuclk_rates));
-	return 0;
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+
+static void __init rk3288_clk_init(struct device_node *np)
+{
+	rk3288_common_init(np, RK3288_CRU);
 }
 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
+
+static void __init rk3288w_clk_init(struct device_node *np)
+{
+	rk3288_common_init(np, RK3288W_CRU);
+}
+CLK_OF_DECLARE(rk3288w_cru, "rockchip,rk3288w-cru", rk3288w_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 833e9bed0e..dd542c2e20 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -3,6 +3,9 @@
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
  *
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
+ *
  * based on
  *
  * samsung/clk.c
@@ -14,10 +17,13 @@
 #include <common.h>
 #include <malloc.h>
 #include <linux/clk.h>
+#include <regmap.h>
+#include <mfd/syscon.h>
+#include <linux/spinlock.h>
+#include <linux/rational.h>
 #include "clk.h"
-#include <init.h>
 
-/**
+/*
  * Register a clock branch.
  * Most clock branches have a form like
  *
@@ -28,134 +34,366 @@
  * sometimes without one of those components.
  */
 static struct clk *rockchip_clk_register_branch(const char *name,
-		const char **parent_names, u8 num_parents, void __iomem *base,
+		const char *const *parent_names, u8 num_parents,
+		void __iomem *base,
 		int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
-		u8 div_shift, u8 div_width, u8 div_flags,
+		int div_offset, u8 div_shift, u8 div_width, u8 div_flags,
 		struct clk_div_table *div_table, int gate_offset,
-		u8 gate_shift, u8 gate_flags, unsigned long flags
-		)
+		u8 gate_shift, u8 gate_flags, unsigned long flags,
+		spinlock_t *lock)
 {
 	struct clk *clk;
-	struct clk *mux = NULL;
-	struct clk *gate = NULL;
-	struct clk *div = NULL;
+	struct clk_mux *mux = NULL;
+	struct clk_gate *gate = NULL;
+	struct clk_divider *div = NULL;
+	int ret;
 
 	if (num_parents > 1) {
-		mux = clk_mux_alloc(name, 0, base + muxdiv_offset, mux_shift,
-		    mux_width, parent_names, num_parents, mux_flags);
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
 		if (!mux)
 			return ERR_PTR(-ENOMEM);
+
+		mux->reg = base + muxdiv_offset;
+		mux->shift = mux_shift;
+		mux->width = mux_width;
+		mux->flags = mux_flags;
+		mux->lock = lock;
+		mux->hw.clk.ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
+							: &clk_mux_ops;
 	}
 
 	if (gate_offset >= 0) {
-		gate = clk_gate_alloc(name, *parent_names, base + gate_offset,
-		    gate_shift, flags, gate_flags);
-		if (!gate)
-			return ERR_PTR(-ENOMEM);
+		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+		if (!gate) {
+			ret = -ENOMEM;
+			goto err_gate;
+		}
+
+		gate->flags = gate_flags;
+		gate->reg = base + gate_offset;
+		gate->shift = gate_shift;
+		gate->lock = lock;
+		gate->hw.clk.ops = &clk_gate_ops;
 	}
 
 	if (div_width > 0) {
-		div = clk_divider_alloc(name, *parent_names, 0,
-		    base + muxdiv_offset, div_shift, div_width, div_flags);
-		if (!div)
-			return ERR_PTR(-ENOMEM);
+		div = kzalloc(sizeof(*div), GFP_KERNEL);
+		if (!div) {
+			ret = -ENOMEM;
+			goto err_div;
+		}
+
+		div->flags = div_flags;
+		if (div_offset)
+			div->reg = base + div_offset;
+		else
+			div->reg = base + muxdiv_offset;
+		div->shift = div_shift;
+		div->width = div_width;
+		div->lock = lock;
+		div->table = div_table;
+		div->hw.clk.ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+						? &clk_divider_ro_ops
+						: &clk_divider_ops;
 	}
 
 	clk = clk_register_composite(name, parent_names, num_parents,
-				     mux,
-				     div,
-				     gate,
-				     flags);
+				       mux ? &mux->hw.clk : NULL,
+				       div ? &div->hw.clk : NULL,
+				       gate ? &gate->hw.clk : NULL,
+				       flags);
+	if (IS_ERR(clk)) {
+		kfree(div);
+		kfree(gate);
+		return ERR_CAST(clk);
+	}
 
 	return clk;
+err_div:
+	kfree(gate);
+err_gate:
+	kfree(mux);
+	return ERR_PTR(ret);
+}
+
+struct rockchip_clk_frac {
+	struct clk_fractional_divider		div;
+	struct clk_gate				gate;
+
+	struct clk_mux				mux;
+	const struct clk_ops			*mux_ops;
+	int					mux_frac_idx;
+
+	bool					rate_change_remuxed;
+	int					rate_change_idx;
+};
+
+/*
+ * fractional divider must set that denominator is 20 times larger than
+ * numerator to generate precise clock frequency.
+ */
+static void rockchip_fractional_approximation(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate,
+		unsigned long *m, unsigned long *n)
+{
+	struct clk_fractional_divider *fd = to_clk_fd(hw);
+	unsigned long p_rate, p_parent_rate;
+	struct clk_hw *p_parent;
+	unsigned long scale;
+
+	p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
+	if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
+		p_parent = clk_hw_get_parent(clk_hw_get_parent(hw));
+		p_parent_rate = clk_hw_get_rate(p_parent);
+		*parent_rate = p_parent_rate;
+	}
+
+	/*
+	 * Get rate closer to *parent_rate to guarantee there is no overflow
+	 * for m and n. In the result it will be the nearest rate left shifted
+	 * by (scale - fd->nwidth) bits.
+	 */
+	scale = fls_long(*parent_rate / rate - 1);
+	if (scale > fd->nwidth)
+		rate <<= scale - fd->nwidth;
+
+	rational_best_approximation(rate, *parent_rate,
+			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+			m, n);
 }
 
-static struct clk *rockchip_clk_register_frac_branch(const char *name,
-		const char **parent_names, u8 num_parents, void __iomem *base,
-		int muxdiv_offset, u8 div_flags,
+static struct clk *rockchip_clk_register_frac_branch(
+		struct rockchip_clk_provider *ctx, const char *name,
+		const char *const *parent_names, u8 num_parents,
+		void __iomem *base, int muxdiv_offset, u8 div_flags,
 		int gate_offset, u8 gate_shift, u8 gate_flags,
-		unsigned long flags)
+		unsigned long flags, struct rockchip_clk_branch *child,
+		spinlock_t *lock)
 {
 	struct clk *clk;
-	struct clk *gate = NULL;
-	struct clk *div = NULL;
-
-	if (gate_offset >= 0) {
-		gate = clk_gate_alloc(name, *parent_names, base + gate_offset,
-		    gate_shift, flags, gate_flags);
-		if (!gate)
-			return ERR_PTR(-ENOMEM);
-	}
+	struct rockchip_clk_frac *frac;
+	struct clk_gate *gate = NULL;
+	struct clk_fractional_divider *div = NULL;
 
 	if (muxdiv_offset < 0)
 		return ERR_PTR(-EINVAL);
 
-	div = clk_fractional_divider_alloc(name, *parent_names, flags,
-		     base + muxdiv_offset, 16, 16, 0, 16, div_flags);
-	if (!div)
+	if (child && child->branch_type != branch_mux) {
+		pr_err("%s: fractional child clock for %s can only be a mux\n",
+		       __func__, name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	frac = kzalloc(sizeof(*frac), GFP_KERNEL);
+	if (!frac)
 		return ERR_PTR(-ENOMEM);
 
+	if (gate_offset >= 0) {
+		gate = &frac->gate;
+		gate->flags = gate_flags;
+		gate->reg = base + gate_offset;
+		gate->shift = gate_shift;
+		gate->lock = lock;
+		gate->hw.clk.ops = &clk_gate_ops;
+	}
+
+	div = &frac->div;
+	div->flags = div_flags;
+	div->reg = base + muxdiv_offset;
+	div->mshift = 16;
+	div->mwidth = 16;
+	div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
+	div->nshift = 0;
+	div->nwidth = 16;
+	div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
+	div->lock = lock;
+	div->approximation = rockchip_fractional_approximation;
+	div->hw.clk.ops = &clk_fractional_divider_ops;
+
 	clk = clk_register_composite(name, parent_names, num_parents,
-				     NULL,
-				     div,
-				     gate,
-				     flags);
+				       NULL,
+				       &div->hw.clk,
+				       gate ? &gate->hw.clk : NULL,
+				       flags | CLK_SET_RATE_UNGATE);
+	if (IS_ERR(clk)) {
+		kfree(frac);
+		return ERR_CAST(clk);
+	}
+
+	if (child) {
+		struct clk_mux *frac_mux = &frac->mux;
+		struct clk_init_data init;
+		struct clk *mux_clk;
+
+		frac->mux_frac_idx = match_string(child->parent_names,
+						  child->num_parents, name);
+		frac->mux_ops = &clk_mux_ops;
+
+		frac_mux->reg = base + child->muxdiv_offset;
+		frac_mux->shift = child->mux_shift;
+		frac_mux->width = child->mux_width;
+		frac_mux->flags = child->mux_flags;
+		frac_mux->lock = lock;
+		frac_mux->hw.init = &init;
+
+		init.name = child->name;
+		init.flags = child->flags | CLK_SET_RATE_PARENT;
+		init.ops = frac->mux_ops;
+		init.parent_names = child->parent_names;
+		init.num_parents = child->num_parents;
+
+		mux_clk = clk_register(NULL, &frac_mux->hw);
+		if (IS_ERR(mux_clk)) {
+			kfree(frac);
+			return mux_clk;
+		}
+
+		rockchip_clk_add_lookup(ctx, mux_clk, child->id);
+
+		/* notifier on the fraction divider to catch rate changes */
+		if (frac->mux_frac_idx >= 0) {
+			pr_debug("%s: found fractional parent in mux at pos %d\n",
+				 __func__, frac->mux_frac_idx);
+		} else {
+			pr_warn("%s: could not find %s as parent of %s, rate changes may not work\n",
+				__func__, name, child->name);
+		}
+	}
 
 	return clk;
 }
 
-static struct clk **clk_table;
-static void __iomem *reg_base;
-static struct clk_onecell_data clk_data;
-static struct device_node *cru_node;
+static struct clk *rockchip_clk_register_factor_branch(const char *name,
+		const char *const *parent_names, u8 num_parents,
+		void __iomem *base, unsigned int mult, unsigned int div,
+		int gate_offset, u8 gate_shift, u8 gate_flags,
+		unsigned long flags, spinlock_t *lock)
+{
+	struct clk *clk;
+	struct clk_gate *gate = NULL;
+	struct clk_fixed_factor *fix = NULL;
+
+	/* without gate, register a simple factor clock */
+	if (gate_offset == 0) {
+		return clk_register_fixed_factor(NULL, name,
+				parent_names[0], flags, mult,
+				div);
+	}
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->flags = gate_flags;
+	gate->reg = base + gate_offset;
+	gate->shift = gate_shift;
+	gate->lock = lock;
+	gate->hw.clk.ops = &clk_gate_ops;
+
+	fix = kzalloc(sizeof(*fix), GFP_KERNEL);
+	if (!fix) {
+		kfree(gate);
+		return ERR_PTR(-ENOMEM);
+	}
 
-void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
-			      unsigned long nr_clks)
+	fix->mult = mult;
+	fix->div = div;
+	fix->hw.clk.ops = &clk_fixed_factor_ops;
+
+	clk = clk_register_composite(name, parent_names, num_parents,
+				       NULL,
+				       &fix->hw.clk,
+				       &gate->hw.clk, flags);
+	if (IS_ERR(clk)) {
+		kfree(fix);
+		kfree(gate);
+		return ERR_CAST(clk);
+	}
+
+	return clk;
+}
+
+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
+						void __iomem *base,
+						unsigned long nr_clks)
 {
-	reg_base = base;
-	cru_node = np;
+	struct rockchip_clk_provider *ctx;
+	struct clk **clk_table;
+	int i;
+
+	ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
 
-	clk_table = calloc(nr_clks, sizeof(struct clk *));
+	clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
 	if (!clk_table)
-		pr_err("%s: could not allocate clock lookup table\n", __func__);
+		goto err_free;
+
+	for (i = 0; i < nr_clks; ++i)
+		clk_table[i] = ERR_PTR(-ENOENT);
+
+	ctx->reg_base = base;
+	ctx->clk_data.clks = clk_table;
+	ctx->clk_data.clk_num = nr_clks;
+	ctx->cru_node = np;
+	spin_lock_init(&ctx->lock);
+
+	ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
+						   "rockchip,grf");
+
+	return ctx;
 
-	clk_data.clks = clk_table;
-	clk_data.clk_num = nr_clks;
-	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+err_free:
+	kfree(ctx);
+	return ERR_PTR(-ENOMEM);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_init);
 
-void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
+void rockchip_clk_of_add_provider(struct device_node *np,
+				  struct rockchip_clk_provider *ctx)
 {
-	if (clk_table && id)
-		clk_table[id] = clk;
+	if (of_clk_add_provider(np, of_clk_src_onecell_get,
+				&ctx->clk_data))
+		pr_err("%s: could not register clk provider\n", __func__);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_of_add_provider);
 
-void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
+void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
+			     struct clk *clk, unsigned int id)
+{
+	if (ctx->clk_data.clks && id)
+		ctx->clk_data.clks[id] = clk;
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_add_lookup);
+
+void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
+				struct rockchip_pll_clock *list,
 				unsigned int nr_pll, int grf_lock_offset)
 {
 	struct clk *clk;
 	int idx;
 
 	for (idx = 0; idx < nr_pll; idx++, list++) {
-		clk = rockchip_clk_register_pll(list->type, list->name,
+		clk = rockchip_clk_register_pll(ctx, list->type, list->name,
 				list->parent_names, list->num_parents,
-				reg_base, list->con_offset, grf_lock_offset,
+				list->con_offset, grf_lock_offset,
 				list->lock_shift, list->mode_offset,
 				list->mode_shift, list->rate_table,
-				list->pll_flags);
+				list->flags, list->pll_flags);
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n", __func__,
 				list->name);
 			continue;
 		}
 
-		rockchip_clk_add_lookup(clk, list->id);
+		rockchip_clk_add_lookup(ctx, clk, list->id);
 	}
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
 
-void __init rockchip_clk_register_branches(
-				      struct rockchip_clk_branch *list,
-				      unsigned int nr_clk)
+void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+				    struct rockchip_clk_branch *list,
+				    unsigned int nr_clk)
 {
 	struct clk *clk = NULL;
 	unsigned int idx;
@@ -167,50 +405,89 @@ void __init rockchip_clk_register_branches(
 		/* catch simple muxes */
 		switch (list->branch_type) {
 		case branch_mux:
-			clk = clk_mux(list->name, flags,
-			    reg_base + list->muxdiv_offset, list->mux_shift,
-			    list->mux_width, list->parent_names,
-			    list->num_parents, list->mux_flags);
+			clk = clk_register_mux(NULL, list->name,
+				list->parent_names, list->num_parents,
+				flags, ctx->reg_base + list->muxdiv_offset,
+				list->mux_shift, list->mux_width,
+				list->mux_flags, &ctx->lock);
+			break;
+		case branch_muxgrf:
+			clk = rockchip_clk_register_muxgrf(list->name,
+				list->parent_names, list->num_parents,
+				flags, ctx->grf, list->muxdiv_offset,
+				list->mux_shift, list->mux_width,
+				list->mux_flags);
 			break;
 		case branch_divider:
 			if (list->div_table)
-				clk = clk_divider_table(list->name,
-				    list->parent_names[0], flags,
-				    reg_base + list->muxdiv_offset,
-				    list->div_shift, list->div_width,
-				    list->div_table, list->div_flags);
+				clk = clk_register_divider_table(NULL,
+					list->name, list->parent_names[0],
+					flags,
+					ctx->reg_base + list->muxdiv_offset,
+					list->div_shift, list->div_width,
+					list->div_flags, list->div_table,
+					&ctx->lock);
 			else
-				clk = clk_divider(list->name,
-				    list->parent_names[0], flags,
-				    reg_base + list->muxdiv_offset,
-				    list->div_shift, list->div_width,
-				    list->div_flags);
+				clk = clk_register_divider(NULL, list->name,
+					list->parent_names[0], flags,
+					ctx->reg_base + list->muxdiv_offset,
+					list->div_shift, list->div_width,
+					list->div_flags, &ctx->lock);
 			break;
 		case branch_fraction_divider:
-			clk = rockchip_clk_register_frac_branch(list->name,
+			clk = rockchip_clk_register_frac_branch(ctx, list->name,
 				list->parent_names, list->num_parents,
-				reg_base, list->muxdiv_offset, list->div_flags,
+				ctx->reg_base, list->muxdiv_offset,
+				list->div_flags,
 				list->gate_offset, list->gate_shift,
-				list->gate_flags, flags);
+				list->gate_flags, flags, list->child,
+				&ctx->lock);
+			break;
+		case branch_half_divider:
 			break;
 		case branch_gate:
 			flags |= CLK_SET_RATE_PARENT;
 
-			clk = clk_gate(list->name, list->parent_names[0],
-			    reg_base + list->gate_offset, list->gate_shift,
-			    flags, list->gate_flags);
+			clk = clk_register_gate(NULL, list->name,
+				list->parent_names[0], flags,
+				ctx->reg_base + list->gate_offset,
+				list->gate_shift, list->gate_flags, &ctx->lock);
 			break;
 		case branch_composite:
 			clk = rockchip_clk_register_branch(list->name,
 				list->parent_names, list->num_parents,
-				reg_base, list->muxdiv_offset, list->mux_shift,
+				ctx->reg_base, list->muxdiv_offset,
+				list->mux_shift,
 				list->mux_width, list->mux_flags,
-				list->div_shift, list->div_width,
+				list->div_offset, list->div_shift, list->div_width,
 				list->div_flags, list->div_table,
 				list->gate_offset, list->gate_shift,
-				list->gate_flags, flags);
+				list->gate_flags, flags, &ctx->lock);
 			break;
 		case branch_mmc:
+			clk = rockchip_clk_register_mmc(
+				list->name,
+				list->parent_names, list->num_parents,
+				ctx->reg_base + list->muxdiv_offset,
+				list->div_shift
+			);
+			break;
+		case branch_inverter:
+			clk = rockchip_clk_register_inverter(
+				list->name, list->parent_names,
+				list->num_parents,
+				ctx->reg_base + list->muxdiv_offset,
+				list->div_shift, list->div_flags, &ctx->lock);
+			break;
+		case branch_factor:
+			clk = rockchip_clk_register_factor_branch(
+				list->name, list->parent_names,
+				list->num_parents, ctx->reg_base,
+				list->div_shift, list->div_width,
+				list->gate_offset, list->gate_shift,
+				list->gate_flags, flags, &ctx->lock);
+			break;
+		case branch_ddrclk:
 			break;
 		}
 
@@ -227,32 +504,36 @@ void __init rockchip_clk_register_branches(
 			continue;
 		}
 
-		rockchip_clk_add_lookup(clk, list->id);
+		rockchip_clk_add_lookup(ctx, clk, list->id);
 	}
 }
-
-void __init rockchip_clk_register_armclk(unsigned int lookup_id,
-			const char *name, const char **parent_names,
-			u8 num_parents,
-			const struct rockchip_cpuclk_reg_data *reg_data,
-			const struct rockchip_cpuclk_rate_table *rates,
-			int nrates)
+EXPORT_SYMBOL_GPL(rockchip_clk_register_branches);
+
+void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
+				  unsigned int lookup_id,
+				  const char *name, const char *const *parent_names,
+				  u8 num_parents,
+				  const struct rockchip_cpuclk_reg_data *reg_data,
+				  const struct rockchip_cpuclk_rate_table *rates,
+				  int nrates)
 {
 	struct clk *clk;
 
 	clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
-					   reg_data, rates, nrates, reg_base
-					   );
+					   reg_data, rates, nrates,
+					   ctx->reg_base, &ctx->lock);
 	if (IS_ERR(clk)) {
 		pr_err("%s: failed to register clock %s: %ld\n",
 		       __func__, name, PTR_ERR(clk));
 		return;
 	}
 
-	rockchip_clk_add_lookup(clk, lookup_id);
+	rockchip_clk_add_lookup(ctx, clk, lookup_id);
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
 
-void __init rockchip_clk_protect_critical(const char *clocks[], int nclocks)
+void rockchip_clk_protect_critical(const char *const clocks[],
+				   int nclocks)
 {
 	int i;
 
@@ -260,7 +541,7 @@ void __init rockchip_clk_protect_critical(const char *clocks[], int nclocks)
 	for (i = 0; i < nclocks; i++) {
 		struct clk *clk = __clk_lookup(clocks[i]);
 
-		if (clk)
-			clk_enable(clk);
+		clk_enable(clk);
 	}
 }
+EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 006225b7e8..c17da6e663 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -3,6 +3,9 @@
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
  *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
+ *
  * based on
  *
  * samsung/clk.h
@@ -17,30 +20,99 @@
 #include <io.h>
 #include <linux/clk.h>
 
-/* To keep changes from kernel smaller */
-#define CLK_GATE_SET_TO_DISABLE	CLK_GATE_INVERTED
-#define CLK_GET_RATE_NOCACHE 0
+struct clk;
+#define writel_relaxed	writel
+#define readl_relaxed	readl
 
 #define HIWORD_UPDATE(val, mask, shift) \
 		((val) << (shift) | (mask) << ((shift) + 16))
 
-/* register positions shared by RK2928, RK3066 and RK3188 */
-#define RK2928_PLL_CON(x)		(x * 0x4)
+/* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
+#define BOOST_PLL_H_CON(x)		((x) * 0x4)
+#define BOOST_CLK_CON			0x0008
+#define BOOST_BOOST_CON			0x000c
+#define BOOST_SWITCH_CNT		0x0010
+#define BOOST_HIGH_PERF_CNT0		0x0014
+#define BOOST_HIGH_PERF_CNT1		0x0018
+#define BOOST_STATIS_THRESHOLD		0x001c
+#define BOOST_SHORT_SWITCH_CNT		0x0020
+#define BOOST_SWITCH_THRESHOLD		0x0024
+#define BOOST_FSM_STATUS		0x0028
+#define BOOST_PLL_L_CON(x)		((x) * 0x4 + 0x2c)
+#define BOOST_RECOVERY_MASK		0x1
+#define BOOST_RECOVERY_SHIFT		1
+#define BOOST_SW_CTRL_MASK		0x1
+#define BOOST_SW_CTRL_SHIFT		2
+#define BOOST_LOW_FREQ_EN_MASK		0x1
+#define BOOST_LOW_FREQ_EN_SHIFT		3
+#define BOOST_BUSY_STATE		BIT(8)
+
+#define PX30_PLL_CON(x)			((x) * 0x4)
+#define PX30_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define PX30_CLKGATE_CON(x)		((x) * 0x4 + 0x200)
+#define PX30_GLB_SRST_FST		0xb8
+#define PX30_GLB_SRST_SND		0xbc
+#define PX30_SOFTRST_CON(x)		((x) * 0x4 + 0x300)
+#define PX30_MODE_CON			0xa0
+#define PX30_MISC_CON			0xa4
+#define PX30_SDMMC_CON0			0x380
+#define PX30_SDMMC_CON1			0x384
+#define PX30_SDIO_CON0			0x388
+#define PX30_SDIO_CON1			0x38c
+#define PX30_EMMC_CON0			0x390
+#define PX30_EMMC_CON1			0x394
+
+#define PX30_PMU_PLL_CON(x)		((x) * 0x4)
+#define PX30_PMU_CLKSEL_CON(x)		((x) * 0x4 + 0x40)
+#define PX30_PMU_CLKGATE_CON(x)		((x) * 0x4 + 0x80)
+#define PX30_PMU_MODE			0x0020
+
+#define RV1108_PLL_CON(x)		((x) * 0x4)
+#define RV1108_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
+#define RV1108_CLKGATE_CON(x)		((x) * 0x4 + 0x120)
+#define RV1108_SOFTRST_CON(x)		((x) * 0x4 + 0x180)
+#define RV1108_GLB_SRST_FST		0x1c0
+#define RV1108_GLB_SRST_SND		0x1c4
+#define RV1108_MISC_CON			0x1cc
+#define RV1108_SDMMC_CON0		0x1d8
+#define RV1108_SDMMC_CON1		0x1dc
+#define RV1108_SDIO_CON0		0x1e0
+#define RV1108_SDIO_CON1		0x1e4
+#define RV1108_EMMC_CON0		0x1e8
+#define RV1108_EMMC_CON1		0x1ec
+
+#define RK2928_PLL_CON(x)		((x) * 0x4)
 #define RK2928_MODE_CON		0x40
-#define RK2928_CLKSEL_CON(x)	(x * 0x4 + 0x44)
-#define RK2928_CLKGATE_CON(x)	(x * 0x4 + 0xd0)
+#define RK2928_CLKSEL_CON(x)	((x) * 0x4 + 0x44)
+#define RK2928_CLKGATE_CON(x)	((x) * 0x4 + 0xd0)
 #define RK2928_GLB_SRST_FST		0x100
 #define RK2928_GLB_SRST_SND		0x104
-#define RK2928_SOFTRST_CON(x)	(x * 0x4 + 0x110)
+#define RK2928_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 #define RK2928_MISC_CON		0x134
 
+#define RK3036_SDMMC_CON0		0x144
+#define RK3036_SDMMC_CON1		0x148
+#define RK3036_SDIO_CON0		0x14c
+#define RK3036_SDIO_CON1		0x150
+#define RK3036_EMMC_CON0		0x154
+#define RK3036_EMMC_CON1		0x158
+
+#define RK3228_GLB_SRST_FST		0x1f0
+#define RK3228_GLB_SRST_SND		0x1f4
+#define RK3228_SDMMC_CON0		0x1c0
+#define RK3228_SDMMC_CON1		0x1c4
+#define RK3228_SDIO_CON0		0x1c8
+#define RK3228_SDIO_CON1		0x1cc
+#define RK3228_EMMC_CON0		0x1d8
+#define RK3228_EMMC_CON1		0x1dc
+
 #define RK3288_PLL_CON(x)		RK2928_PLL_CON(x)
 #define RK3288_MODE_CON			0x50
-#define RK3288_CLKSEL_CON(x)		(x * 0x4 + 0x60)
-#define RK3288_CLKGATE_CON(x)		(x * 0x4 + 0x160)
+#define RK3288_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
+#define RK3288_CLKGATE_CON(x)		((x) * 0x4 + 0x160)
 #define RK3288_GLB_SRST_FST		0x1b0
 #define RK3288_GLB_SRST_SND		0x1b4
-#define RK3288_SOFTRST_CON(x)		(x * 0x4 + 0x1b8)
+#define RK3288_SOFTRST_CON(x)		((x) * 0x4 + 0x1b8)
 #define RK3288_MISC_CON			0x1e8
 #define RK3288_SDMMC_CON0		0x200
 #define RK3288_SDMMC_CON1		0x204
@@ -51,41 +123,175 @@
 #define RK3288_EMMC_CON0		0x218
 #define RK3288_EMMC_CON1		0x21c
 
+#define RK3308_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3308_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3308_CLKGATE_CON(x)		((x) * 0x4 + 0x300)
+#define RK3308_GLB_SRST_FST		0xb8
+#define RK3308_SOFTRST_CON(x)		((x) * 0x4 + 0x400)
+#define RK3308_MODE_CON			0xa0
+#define RK3308_SDMMC_CON0		0x480
+#define RK3308_SDMMC_CON1		0x484
+#define RK3308_SDIO_CON0		0x488
+#define RK3308_SDIO_CON1		0x48c
+#define RK3308_EMMC_CON0		0x490
+#define RK3308_EMMC_CON1		0x494
+
+#define RK3328_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3328_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3328_CLKGATE_CON(x)		((x) * 0x4 + 0x200)
+#define RK3328_GRFCLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3328_GLB_SRST_FST		0x9c
+#define RK3328_GLB_SRST_SND		0x98
+#define RK3328_SOFTRST_CON(x)		((x) * 0x4 + 0x300)
+#define RK3328_MODE_CON			0x80
+#define RK3328_MISC_CON			0x84
+#define RK3328_SDMMC_CON0		0x380
+#define RK3328_SDMMC_CON1		0x384
+#define RK3328_SDIO_CON0		0x388
+#define RK3328_SDIO_CON1		0x38c
+#define RK3328_EMMC_CON0		0x390
+#define RK3328_EMMC_CON1		0x394
+#define RK3328_SDMMC_EXT_CON0		0x398
+#define RK3328_SDMMC_EXT_CON1		0x39C
+
+#define RK3368_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3368_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3368_CLKGATE_CON(x)		((x) * 0x4 + 0x200)
+#define RK3368_GLB_SRST_FST		0x280
+#define RK3368_GLB_SRST_SND		0x284
+#define RK3368_SOFTRST_CON(x)		((x) * 0x4 + 0x300)
+#define RK3368_MISC_CON			0x380
+#define RK3368_SDMMC_CON0		0x400
+#define RK3368_SDMMC_CON1		0x404
+#define RK3368_SDIO0_CON0		0x408
+#define RK3368_SDIO0_CON1		0x40c
+#define RK3368_SDIO1_CON0		0x410
+#define RK3368_SDIO1_CON1		0x414
+#define RK3368_EMMC_CON0		0x418
+#define RK3368_EMMC_CON1		0x41c
+
+#define RK3399_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3399_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3399_CLKGATE_CON(x)		((x) * 0x4 + 0x300)
+#define RK3399_SOFTRST_CON(x)		((x) * 0x4 + 0x400)
+#define RK3399_GLB_SRST_FST		0x500
+#define RK3399_GLB_SRST_SND		0x504
+#define RK3399_GLB_CNT_TH		0x508
+#define RK3399_MISC_CON			0x50c
+#define RK3399_RST_CON			0x510
+#define RK3399_RST_ST			0x514
+#define RK3399_SDMMC_CON0		0x580
+#define RK3399_SDMMC_CON1		0x584
+#define RK3399_SDIO_CON0		0x588
+#define RK3399_SDIO_CON1		0x58c
+
+#define RK3399_PMU_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3399_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x80)
+#define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
+#define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
+
+#define RK3568_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3568_MODE_CON0		0xc0
+#define RK3568_MISC_CON0		0xc4
+#define RK3568_MISC_CON1		0xc8
+#define RK3568_MISC_CON2		0xcc
+#define RK3568_GLB_CNT_TH		0xd0
+#define RK3568_GLB_SRST_FST		0xd4
+#define RK3568_GLB_SRST_SND		0xd8
+#define RK3568_GLB_RST_CON		0xdc
+#define RK3568_GLB_RST_ST		0xe0
+#define RK3568_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define RK3568_CLKGATE_CON(x)		((x) * 0x4 + 0x300)
+#define RK3568_SOFTRST_CON(x)		((x) * 0x4 + 0x400)
+#define RK3568_SDMMC0_CON0		0x580
+#define RK3568_SDMMC0_CON1		0x584
+#define RK3568_SDMMC1_CON0		0x588
+#define RK3568_SDMMC1_CON1		0x58c
+#define RK3568_SDMMC2_CON0		0x590
+#define RK3568_SDMMC2_CON1		0x594
+#define RK3568_EMMC_CON0		0x598
+#define RK3568_EMMC_CON1		0x59c
+
+#define RK3568_PMU_PLL_CON(x)		RK2928_PLL_CON(x)
+#define RK3568_PMU_MODE_CON0		0x80
+#define RK3568_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x100)
+#define RK3568_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x180)
+#define RK3568_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x200)
+
 enum rockchip_pll_type {
+	pll_rk3036,
 	pll_rk3066,
+	pll_rk3328,
+	pll_rk3399,
 };
 
+#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
+			_postdiv2, _dsmpd, _frac)		\
+{								\
+	.rate	= _rate##U,					\
+	.fbdiv = _fbdiv,					\
+	.postdiv1 = _postdiv1,					\
+	.refdiv = _refdiv,					\
+	.postdiv2 = _postdiv2,					\
+	.dsmpd = _dsmpd,					\
+	.frac = _frac,						\
+}
+
 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)	\
 {						\
 	.rate	= _rate##U,			\
 	.nr = _nr,				\
 	.nf = _nf,				\
 	.no = _no,				\
-	.bwadj = (_nf >> 1),			\
+	.nb = ((_nf) < 2) ? 1 : (_nf) >> 1,	\
 }
 
-#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw)	\
+#define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)		\
 {								\
 	.rate	= _rate##U,					\
 	.nr = _nr,						\
 	.nf = _nf,						\
 	.no = _no,						\
-	.bwadj = _bw,						\
+	.nb = _nb,						\
 }
 
+/**
+ * struct rockchip_clk_provider - information about clock provider
+ * @reg_base: virtual address for the register base.
+ * @clk_data: holds clock related data like clk* and number of clocks.
+ * @cru_node: device-node of the clock-provider
+ * @grf: regmap of the general-register-files syscon
+ * @lock: maintains exclusion between callbacks for a given clock-provider.
+ */
+struct rockchip_clk_provider {
+	void __iomem *reg_base;
+	struct clk_onecell_data clk_data;
+	struct device_node *cru_node;
+	struct regmap *grf;
+	spinlock_t lock;
+};
+
 struct rockchip_pll_rate_table {
 	unsigned long rate;
 	unsigned int nr;
 	unsigned int nf;
 	unsigned int no;
-	unsigned int bwadj;
+	unsigned int nb;
+	/* for RK3036/RK3399 */
+	unsigned int fbdiv;
+	unsigned int postdiv1;
+	unsigned int refdiv;
+	unsigned int postdiv2;
+	unsigned int dsmpd;
+	unsigned int frac;
 };
 
 /**
- * struct rockchip_pll_clock: information about pll clock
+ * struct rockchip_pll_clock - information about pll clock
  * @id: platform specific id of the clock.
  * @name: name of this pll clock.
- * @parent_name: name of the parent clock.
+ * @parent_names: name of the parent clock.
+ * @num_parents: number of parents
  * @flags: optional flags for basic clock.
  * @con_offset: offset of the register for configuring the PLL.
  * @mode_offset: offset of the register for configuring the PLL-mode.
@@ -102,7 +308,7 @@ struct rockchip_pll_rate_table {
 struct rockchip_pll_clock {
 	unsigned int		id;
 	const char		*name;
-	const char		**parent_names;
+	const char		*const *parent_names;
 	u8			num_parents;
 	unsigned long		flags;
 	int			con_offset;
@@ -133,71 +339,111 @@ struct rockchip_pll_clock {
 		.rate_table	= _rtable,				\
 	}
 
-struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
-		const char *name, const char **parent_names, u8 num_parents,
-		void __iomem *base, int con_offset, int grf_lock_offset,
-		int lock_shift, int reg_mode, int mode_shift,
+struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+		enum rockchip_pll_type pll_type,
+		const char *name, const char *const *parent_names,
+		u8 num_parents, int con_offset, int grf_lock_offset,
+		int lock_shift, int mode_offset, int mode_shift,
 		struct rockchip_pll_rate_table *rate_table,
-		u8 clk_pll_flags);
+		unsigned long flags, u8 clk_pll_flags);
 
 struct rockchip_cpuclk_clksel {
 	int reg;
 	u32 val;
 };
 
-#define ROCKCHIP_CPUCLK_NUM_DIVIDERS	2
+#define ROCKCHIP_CPUCLK_NUM_DIVIDERS	5
+#define ROCKCHIP_CPUCLK_MAX_CORES	4
 struct rockchip_cpuclk_rate_table {
 	unsigned long prate;
 	struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
 };
 
 /**
- * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock
- * @core_reg:		register offset of the core settings register
- * @div_core_shift:	core divider offset used to divide the pll value
- * @div_core_mask:	core divider mask
+ * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
+ * @core_reg[]:	register offset of the cores setting register
+ * @div_core_shift[]:	cores divider offset used to divide the pll value
+ * @div_core_mask[]:	cores divider mask
+ * @num_cores:	number of cpu cores
+ * @mux_core_main:	mux value to select main parent of core
  * @mux_core_shift:	offset of the core multiplexer
+ * @mux_core_mask:	core multiplexer mask
  */
 struct rockchip_cpuclk_reg_data {
-	int		core_reg;
-	u8		div_core_shift;
-	u32		div_core_mask;
-	int		mux_core_reg;
-	u8		mux_core_shift;
+	int	core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
+	u8	div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
+	u32	div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
+	int	num_cores;
+	u8	mux_core_alt;
+	u8	mux_core_main;
+	u8	mux_core_shift;
+	u32	mux_core_mask;
 };
 
 struct clk *rockchip_clk_register_cpuclk(const char *name,
-			const char **parent_names, u8 num_parents,
+			const char *const *parent_names, u8 num_parents,
 			const struct rockchip_cpuclk_reg_data *reg_data,
 			const struct rockchip_cpuclk_rate_table *rates,
-			int nrates, void __iomem *reg_base);
+			int nrates, void __iomem *reg_base, spinlock_t *lock);
 
 struct clk *rockchip_clk_register_mmc(const char *name,
-				const char **parent_names, u8 num_parents,
+				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg, int shift);
 
-#define PNAME(x) static const char *x[] __initconst
+/*
+ * DDRCLK flags, including method of setting the rate
+ * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
+ */
+#define ROCKCHIP_DDRCLK_SIP		BIT(0)
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+					 const char *const *parent_names,
+					 u8 num_parents, int mux_offset,
+					 int mux_shift, int mux_width,
+					 int div_shift, int div_width,
+					 int ddr_flags, void __iomem *reg_base,
+					 spinlock_t *lock);
+
+#define ROCKCHIP_INVERTER_HIWORD_MASK	BIT(0)
+
+struct clk *rockchip_clk_register_inverter(const char *name,
+				const char *const *parent_names, u8 num_parents,
+				void __iomem *reg, int shift, int flags,
+				spinlock_t *lock);
+
+struct clk *rockchip_clk_register_muxgrf(const char *name,
+				const char *const *parent_names, u8 num_parents,
+				int flags, struct regmap *grf, int reg,
+				int shift, int width, int mux_flags);
+
+#define PNAME(x) static const char *const x[] __initconst
 
 enum rockchip_clk_branch_type {
 	branch_composite,
 	branch_mux,
+	branch_muxgrf,
 	branch_divider,
 	branch_fraction_divider,
 	branch_gate,
 	branch_mmc,
+	branch_inverter,
+	branch_factor,
+	branch_ddrclk,
+	branch_half_divider,
 };
 
 struct rockchip_clk_branch {
 	unsigned int			id;
 	enum rockchip_clk_branch_type	branch_type;
 	const char			*name;
-	const char			**parent_names;
+	const char			*const *parent_names;
 	u8				num_parents;
 	unsigned long			flags;
 	int				muxdiv_offset;
 	u8				mux_shift;
 	u8				mux_width;
 	u8				mux_flags;
+	int				div_offset;
 	u8				div_shift;
 	u8				div_width;
 	u8				div_flags;
@@ -205,6 +451,7 @@ struct rockchip_clk_branch {
 	int				gate_offset;
 	u8				gate_shift;
 	u8				gate_flags;
+	struct rockchip_clk_branch	*child;
 };
 
 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
@@ -228,6 +475,28 @@ struct rockchip_clk_branch {
 		.gate_flags	= gf,				\
 	}
 
+#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw,	\
+			     mf, do, ds, dw, df, go, gs, gf)	\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_composite,		\
+		.name		= cname,			\
+		.parent_names	= pnames,			\
+		.num_parents	= ARRAY_SIZE(pnames),		\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.mux_shift	= ms,				\
+		.mux_width	= mw,				\
+		.mux_flags	= mf,				\
+		.div_offset	= do,				\
+		.div_shift	= ds,				\
+		.div_width	= dw,				\
+		.div_flags	= df,				\
+		.gate_offset	= go,				\
+		.gate_shift	= gs,				\
+		.gate_flags	= gf,				\
+	}
+
 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,	\
 			go, gs, gf)				\
 	{							\
@@ -302,6 +571,26 @@ struct rockchip_clk_branch {
 		.gate_offset	= -1,				\
 	}
 
+#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,	\
+				mw, mf, ds, dw, df, dt)		\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_composite,		\
+		.name		= cname,			\
+		.parent_names	= pnames,			\
+		.num_parents	= ARRAY_SIZE(pnames),		\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.mux_shift	= ms,				\
+		.mux_width	= mw,				\
+		.mux_flags	= mf,				\
+		.div_shift	= ds,				\
+		.div_width	= dw,				\
+		.div_flags	= df,				\
+		.div_table	= dt,				\
+		.gate_offset	= -1,				\
+	}
+
 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
 	{							\
 		.id		= _id,				\
@@ -319,6 +608,58 @@ struct rockchip_clk_branch {
 		.gate_flags	= gf,				\
 	}
 
+#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_fraction_divider,	\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.div_shift	= 16,				\
+		.div_width	= 16,				\
+		.div_flags	= df,				\
+		.gate_offset	= go,				\
+		.gate_shift	= gs,				\
+		.gate_flags	= gf,				\
+		.child		= ch,				\
+	}
+
+#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_fraction_divider,	\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.div_shift	= 16,				\
+		.div_width	= 16,				\
+		.div_flags	= df,				\
+		.gate_offset	= -1,				\
+		.child		= ch,				\
+	}
+
+#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,	\
+			 ds, dw, df)				\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_ddrclk,		\
+		.name		= cname,			\
+		.parent_names	= pnames,			\
+		.num_parents	= ARRAY_SIZE(pnames),		\
+		.flags		= f,				\
+		.muxdiv_offset  = mo,                           \
+		.mux_shift      = ms,                           \
+		.mux_width      = mw,                           \
+		.div_shift      = ds,                           \
+		.div_width      = dw,                           \
+		.div_flags	= df,				\
+		.gate_offset    = -1,                           \
+	}
+
 #define MUX(_id, cname, pnames, f, o, s, w, mf)			\
 	{							\
 		.id		= _id,				\
@@ -334,6 +675,21 @@ struct rockchip_clk_branch {
 		.gate_offset	= -1,				\
 	}
 
+#define MUXGRF(_id, cname, pnames, f, o, s, w, mf)		\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_muxgrf,		\
+		.name		= cname,			\
+		.parent_names	= pnames,			\
+		.num_parents	= ARRAY_SIZE(pnames),		\
+		.flags		= f,				\
+		.muxdiv_offset	= o,				\
+		.mux_shift	= s,				\
+		.mux_width	= w,				\
+		.mux_flags	= mf,				\
+		.gate_offset	= -1,				\
+	}
+
 #define DIV(_id, cname, pname, f, o, s, w, df)			\
 	{							\
 		.id		= _id,				\
@@ -388,19 +744,69 @@ struct rockchip_clk_branch {
 		.div_shift	= shift,			\
 	}
 
-void rockchip_clk_init(struct device_node *np, void __iomem *base,
-		       unsigned long nr_clks);
-struct regmap *rockchip_clk_get_grf(void);
-void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
-void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
+#define INVERTER(_id, cname, pname, io, is, if)			\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_inverter,		\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.muxdiv_offset	= io,				\
+		.div_shift	= is,				\
+		.div_flags	= if,				\
+	}
+
+#define FACTOR(_id, cname, pname,  f, fm, fd)			\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_factor,		\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.div_shift	= fm,				\
+		.div_width	= fd,				\
+	}
+
+#define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)	\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_factor,		\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.div_shift	= fm,				\
+		.div_width	= fd,				\
+		.gate_offset	= go,				\
+		.gate_shift	= gb,				\
+		.gate_flags	= gf,				\
+	}
+
+/* SGRF clocks are only accessible from secure mode, so not controllable */
+#define SGRF_GATE(_id, cname, pname)				\
+		FACTOR(_id, cname, pname, 0, 1, 1)
+
+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
+			void __iomem *base, unsigned long nr_clks);
+void rockchip_clk_of_add_provider(struct device_node *np,
+				struct rockchip_clk_provider *ctx);
+void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
+			     struct clk *clk, unsigned int id);
+void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+				    struct rockchip_clk_branch *list,
 				    unsigned int nr_clk);
-void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
+void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
+				struct rockchip_pll_clock *pll_list,
 				unsigned int nr_pll, int grf_lock_offset);
-void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
-			const char **parent_names, u8 num_parents,
+void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
+			unsigned int lookup_id, const char *name,
+			const char *const *parent_names, u8 num_parents,
 			const struct rockchip_cpuclk_reg_data *reg_data,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates);
-void rockchip_clk_protect_critical(const char *clocks[], int nclocks);
+void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
+
+#define ROCKCHIP_SOFTRST_HIWORD_MASK	BIT(0)
 
 #endif
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 24/24] clk: Rockchip: Add rk3568 clk support
  2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
                   ` (22 preceding siblings ...)
  2021-06-02  9:55 ` [PATCH 23/24] clk: rockchip: Update to current Linux Sascha Hauer
@ 2021-06-02  9:55 ` Sascha Hauer
  2021-06-09  9:18   ` Ahmad Fatoum
  23 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-02  9:55 UTC (permalink / raw)
  To: Barebox List

This adds clock support for the Rockchip rk3568 SoC. Based on the
corresponding Linux patch merged into v5.13-rc1.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/rockchip/Makefile     |    1 +
 drivers/clk/rockchip/clk-rk3568.c | 1704 +++++++++++++++++++++++++++++
 2 files changed, 1705 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3568.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 9964b331f2..4c387b3a89 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -2,3 +2,4 @@
 obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
 obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
 obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
+obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
new file mode 100644
index 0000000000..d151437c12
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -0,0 +1,1704 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <of.h>
+#include <of_address.h>
+#include <linux/barebox-wrapper.h>
+#include <init.h>
+#include <linux/spinlock.h>
+#include <of_device.h>
+#include <dt-bindings/clock/rk3568-cru.h>
+#include "clk.h"
+
+#define RK3568_GRF_SOC_STATUS0	0x580
+
+enum rk3568_pmu_plls {
+	ppll, hpll,
+};
+
+enum rk3568_plls {
+	apll, dpll, gpll, cpll, npll, vpll,
+};
+
+static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
+	RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0),
+	RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
+	RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
+	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+	RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3568_DIV_ATCLK_CORE_MASK	0x1f
+#define RK3568_DIV_ATCLK_CORE_SHIFT	0
+#define RK3568_DIV_GICCLK_CORE_MASK	0x1f
+#define RK3568_DIV_GICCLK_CORE_SHIFT	8
+#define RK3568_DIV_PCLK_CORE_MASK	0x1f
+#define RK3568_DIV_PCLK_CORE_SHIFT	0
+#define RK3568_DIV_PERIPHCLK_CORE_MASK	0x1f
+#define RK3568_DIV_PERIPHCLK_CORE_SHIFT	8
+#define RK3568_DIV_ACLK_CORE_MASK	0x1f
+#define RK3568_DIV_ACLK_CORE_SHIFT	8
+
+#define RK3568_DIV_SCLK_CORE_MASK	0xf
+#define RK3568_DIV_SCLK_CORE_SHIFT	0
+#define RK3568_MUX_SCLK_CORE_MASK	0x3
+#define RK3568_MUX_SCLK_CORE_SHIFT	8
+#define RK3568_MUX_SCLK_CORE_NPLL_MASK	0x1
+#define RK3568_MUX_SCLK_CORE_NPLL_SHIFT	15
+#define RK3568_MUX_CLK_CORE_APLL_MASK	0x1
+#define RK3568_MUX_CLK_CORE_APLL_SHIFT	7
+#define RK3568_MUX_CLK_PVTPLL_MASK	0x1
+#define RK3568_MUX_CLK_PVTPLL_SHIFT	15
+
+#define RK3568_CLKSEL1(_sclk_core)					\
+{								\
+	.reg = RK3568_CLKSEL_CON(2),				\
+	.val = HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_NPLL_MASK, \
+			RK3568_MUX_SCLK_CORE_NPLL_SHIFT) |		\
+	       HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_MASK, \
+			RK3568_MUX_SCLK_CORE_SHIFT) |		\
+		HIWORD_UPDATE(1, RK3568_DIV_SCLK_CORE_MASK, \
+			RK3568_DIV_SCLK_CORE_SHIFT),		\
+}
+
+#define RK3568_CLKSEL2(_aclk_core)					\
+{								\
+	.reg = RK3568_CLKSEL_CON(5),				\
+	.val = HIWORD_UPDATE(_aclk_core, RK3568_DIV_ACLK_CORE_MASK, \
+			RK3568_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3568_CLKSEL3(_atclk_core, _gic_core)	\
+{								\
+	.reg = RK3568_CLKSEL_CON(3),				\
+	.val = HIWORD_UPDATE(_atclk_core, RK3568_DIV_ATCLK_CORE_MASK, \
+			RK3568_DIV_ATCLK_CORE_SHIFT) |		\
+	       HIWORD_UPDATE(_gic_core, RK3568_DIV_GICCLK_CORE_MASK, \
+			RK3568_DIV_GICCLK_CORE_SHIFT),		\
+}
+
+#define RK3568_CLKSEL4(_pclk_core, _periph_core)	\
+{								\
+	.reg = RK3568_CLKSEL_CON(4),				\
+	.val = HIWORD_UPDATE(_pclk_core, RK3568_DIV_PCLK_CORE_MASK, \
+			RK3568_DIV_PCLK_CORE_SHIFT) |		\
+	       HIWORD_UPDATE(_periph_core, RK3568_DIV_PERIPHCLK_CORE_MASK, \
+			RK3568_DIV_PERIPHCLK_CORE_SHIFT),		\
+}
+
+#define RK3568_CPUCLK_RATE(_prate, _sclk, _acore, _atcore, _gicclk, _pclk, _periph) \
+{								\
+	.prate = _prate##U,					\
+	.divs = {						\
+		RK3568_CLKSEL1(_sclk),				\
+		RK3568_CLKSEL2(_acore),				\
+		RK3568_CLKSEL3(_atcore, _gicclk),		\
+		RK3568_CLKSEL4(_pclk, _periph),			\
+	},							\
+}
+
+static struct rockchip_cpuclk_rate_table rk3568_cpuclk_rates[] __initdata = {
+	RK3568_CPUCLK_RATE(1800000000, 0, 1, 7, 7, 7, 7),
+	RK3568_CPUCLK_RATE(1704000000, 0, 1, 7, 7, 7, 7),
+	RK3568_CPUCLK_RATE(1608000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1584000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1560000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1536000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1512000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1488000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1464000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1440000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1416000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1392000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1368000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1344000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1320000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1296000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1272000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1248000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1224000000, 0, 1, 5, 5, 5, 5),
+	RK3568_CPUCLK_RATE(1200000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(1104000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(1008000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(912000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(816000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(696000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(600000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(408000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(312000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(216000000, 0, 1, 3, 3, 3, 3),
+	RK3568_CPUCLK_RATE(96000000, 0, 1, 3, 3, 3, 3),
+};
+
+static const struct rockchip_cpuclk_reg_data rk3568_cpuclk_data = {
+	.core_reg[0] = RK3568_CLKSEL_CON(0),
+	.div_core_shift[0] = 0,
+	.div_core_mask[0] = 0x1f,
+	.core_reg[1] = RK3568_CLKSEL_CON(0),
+	.div_core_shift[1] = 8,
+	.div_core_mask[1] = 0x1f,
+	.core_reg[2] = RK3568_CLKSEL_CON(1),
+	.div_core_shift[2] = 0,
+	.div_core_mask[2] = 0x1f,
+	.core_reg[3] = RK3568_CLKSEL_CON(1),
+	.div_core_shift[3] = 8,
+	.div_core_mask[3] = 0x1f,
+	.num_cores = 4,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
+	.mux_core_shift = 6,
+	.mux_core_mask = 0x1,
+};
+
+PNAME(mux_pll_p)			= { "xin24m" };
+PNAME(mux_usb480m_p)			= { "xin24m", "usb480m_phy", "clk_rtc_32k" };
+PNAME(mux_armclk_p)			= { "apll", "gpll" };
+PNAME(clk_i2s0_8ch_tx_p)		= { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin_osc0_half" };
+PNAME(clk_i2s0_8ch_rx_p)		= { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin_osc0_half" };
+PNAME(clk_i2s1_8ch_tx_p)		= { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin_osc0_half" };
+PNAME(clk_i2s1_8ch_rx_p)		= { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin_osc0_half" };
+PNAME(clk_i2s2_2ch_p)			= { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin_osc0_half "};
+PNAME(clk_i2s3_2ch_tx_p)		= { "clk_i2s3_2ch_tx_src", "clk_i2s3_2ch_tx_frac", "i2s3_mclkin", "xin_osc0_half" };
+PNAME(clk_i2s3_2ch_rx_p)		= { "clk_i2s3_2ch_rx_src", "clk_i2s3_2ch_rx_frac", "i2s3_mclkin", "xin_osc0_half" };
+PNAME(mclk_spdif_8ch_p)			= { "mclk_spdif_8ch_src", "mclk_spdif_8ch_frac" };
+PNAME(sclk_audpwm_p)			= { "sclk_audpwm_src", "sclk_audpwm_frac" };
+PNAME(sclk_uart1_p)			= { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
+PNAME(sclk_uart2_p)			= { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
+PNAME(sclk_uart3_p)			= { "clk_uart3_src", "clk_uart3_frac", "xin24m" };
+PNAME(sclk_uart4_p)			= { "clk_uart4_src", "clk_uart4_frac", "xin24m" };
+PNAME(sclk_uart5_p)			= { "clk_uart5_src", "clk_uart5_frac", "xin24m" };
+PNAME(sclk_uart6_p)			= { "clk_uart6_src", "clk_uart6_frac", "xin24m" };
+PNAME(sclk_uart7_p)			= { "clk_uart7_src", "clk_uart7_frac", "xin24m" };
+PNAME(sclk_uart8_p)			= { "clk_uart8_src", "clk_uart8_frac", "xin24m" };
+PNAME(sclk_uart9_p)			= { "clk_uart9_src", "clk_uart9_frac", "xin24m" };
+PNAME(sclk_uart0_p)			= { "sclk_uart0_div", "sclk_uart0_frac", "xin24m" };
+PNAME(clk_rtc32k_pmu_p)			= { "clk_32k_pvtm", "xin32k", "clk_rtc32k_frac" };
+PNAME(mpll_gpll_cpll_npll_p)		= { "mpll", "gpll", "cpll", "npll" };
+PNAME(gpll_cpll_npll_p)			= { "gpll", "cpll", "npll" };
+PNAME(npll_gpll_p)			= { "npll", "gpll" };
+PNAME(cpll_gpll_p)			= { "cpll", "gpll" };
+PNAME(gpll_cpll_p)			= { "gpll", "cpll" };
+PNAME(gpll_cpll_npll_vpll_p)		= { "gpll", "cpll", "npll", "vpll" };
+PNAME(apll_gpll_npll_p)			= { "apll", "gpll", "npll" };
+PNAME(sclk_core_pre_p)			= { "sclk_core_src", "npll" };
+PNAME(gpll150_gpll100_gpll75_xin24m_p)	= { "gpll_150m", "gpll_100m", "gpll_75m", "xin24m" };
+PNAME(clk_gpu_pre_mux_p)		= { "clk_gpu_src", "gpu_pvtpll_out" };
+PNAME(clk_npu_pre_ndft_p)		= { "clk_npu_src", "dummy"};
+PNAME(clk_npu_p)			= { "clk_npu_pre_ndft", "npu_pvtpll_out" };
+PNAME(dpll_gpll_cpll_p)			= { "dpll", "gpll", "cpll" };
+PNAME(clk_ddr1x_p)			= { "clk_ddrphy1x_src", "dpll" };
+PNAME(gpll200_gpll150_gpll100_xin24m_p)	= { "gpll_200m", "gpll_150m", "gpll_100m", "xin24m" };
+PNAME(gpll100_gpll75_gpll50_p)		= { "gpll_100m", "gpll_75m", "cpll_50m" };
+PNAME(i2s0_mclkout_tx_p)		= { "clk_i2s0_8ch_tx", "xin_osc0_half" };
+PNAME(i2s0_mclkout_rx_p)		= { "clk_i2s0_8ch_rx", "xin_osc0_half" };
+PNAME(i2s1_mclkout_tx_p)		= { "clk_i2s1_8ch_tx", "xin_osc0_half" };
+PNAME(i2s1_mclkout_rx_p)		= { "clk_i2s1_8ch_rx", "xin_osc0_half" };
+PNAME(i2s2_mclkout_p)			= { "clk_i2s2_2ch", "xin_osc0_half" };
+PNAME(i2s3_mclkout_tx_p)		= { "clk_i2s3_2ch_tx", "xin_osc0_half" };
+PNAME(i2s3_mclkout_rx_p)		= { "clk_i2s3_2ch_rx", "xin_osc0_half" };
+PNAME(mclk_pdm_p)			= { "gpll_300m", "cpll_250m", "gpll_200m", "gpll_100m" };
+PNAME(clk_i2c_p)			= { "gpll_200m", "gpll_100m", "xin24m", "cpll_100m" };
+PNAME(gpll200_gpll150_gpll100_p)	= { "gpll_200m", "gpll_150m", "gpll_100m" };
+PNAME(gpll300_gpll200_gpll100_p)	= { "gpll_300m", "gpll_200m", "gpll_100m" };
+PNAME(clk_nandc_p)			= { "gpll_200m", "gpll_150m", "cpll_100m", "xin24m" };
+PNAME(sclk_sfc_p)			= { "xin24m", "cpll_50m", "gpll_75m", "gpll_100m", "cpll_125m", "gpll_150m" };
+PNAME(gpll200_gpll150_cpll125_p)	= { "gpll_200m", "gpll_150m", "cpll_125m" };
+PNAME(cclk_emmc_p)			= { "xin24m", "gpll_200m", "gpll_150m", "cpll_100m", "cpll_50m", "clk_osc0_div_375k" };
+PNAME(aclk_pipe_p)			= { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
+PNAME(gpll200_cpll125_p)		= { "gpll_200m", "cpll_125m" };
+PNAME(gpll300_gpll200_gpll100_xin24m_p)	= { "gpll_300m", "gpll_200m", "gpll_100m", "xin24m" };
+PNAME(clk_sdmmc_p)			= { "xin24m", "gpll_400m", "gpll_300m", "cpll_100m", "cpll_50m", "clk_osc0_div_750k" };
+PNAME(cpll125_cpll50_cpll25_xin24m_p)	= { "cpll_125m", "cpll_50m", "cpll_25m", "xin24m" };
+PNAME(clk_gmac_ptp_p)			= { "cpll_62p5", "gpll_100m", "cpll_50m", "xin24m" };
+PNAME(cpll333_gpll300_gpll200_p)	= { "cpll_333m", "gpll_300m", "gpll_200m" };
+PNAME(cpll_gpll_hpll_p)			= { "cpll", "gpll", "hpll" };
+PNAME(gpll_usb480m_xin24m_p)		= { "gpll", "usb480m", "xin24m", "xin24m" };
+PNAME(gpll300_cpll250_gpll100_xin24m_p)	= { "gpll_300m", "cpll_250m", "gpll_100m", "xin24m" };
+PNAME(cpll_gpll_hpll_vpll_p)		= { "cpll", "gpll", "hpll", "vpll" };
+PNAME(hpll_vpll_gpll_cpll_p)		= { "hpll", "vpll", "gpll", "cpll" };
+PNAME(gpll400_cpll333_gpll200_p)	= { "gpll_400m", "cpll_333m", "gpll_200m" };
+PNAME(gpll100_gpll75_cpll50_xin24m_p)	= { "gpll_100m", "gpll_75m", "cpll_50m", "xin24m" };
+PNAME(xin24m_gpll100_cpll100_p)		= { "xin24m", "gpll_100m", "cpll_100m" };
+PNAME(gpll_cpll_usb480m_p)		= { "gpll", "cpll", "usb480m" };
+PNAME(gpll100_xin24m_cpll100_p)		= { "gpll_100m", "xin24m", "cpll_100m" };
+PNAME(gpll200_xin24m_cpll100_p)		= { "gpll_200m", "xin24m", "cpll_100m" };
+PNAME(xin24m_32k_p)			= { "xin24m", "clk_rtc_32k" };
+PNAME(cpll500_gpll400_gpll300_xin24m_p)	= { "cpll_500m", "gpll_400m", "gpll_300m", "xin24m" };
+PNAME(gpll400_gpll300_gpll200_xin24m_p)	= { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
+PNAME(xin24m_cpll100_p)			= { "xin24m", "cpll_100m" };
+PNAME(ppll_usb480m_cpll_gpll_p)		= { "ppll", "usb480m", "cpll", "gpll"};
+PNAME(clk_usbphy0_ref_p)		= { "clk_ref24m", "xin_osc0_usbphy0_g" };
+PNAME(clk_usbphy1_ref_p)		= { "clk_ref24m", "xin_osc0_usbphy1_g" };
+PNAME(clk_mipidsiphy0_ref_p)		= { "clk_ref24m", "xin_osc0_mipidsiphy0_g" };
+PNAME(clk_mipidsiphy1_ref_p)		= { "clk_ref24m", "xin_osc0_mipidsiphy1_g" };
+PNAME(clk_wifi_p)			= { "clk_wifi_osc0", "clk_wifi_div" };
+PNAME(clk_pciephy0_ref_p)		= { "clk_pciephy0_osc0", "clk_pciephy0_div" };
+PNAME(clk_pciephy1_ref_p)		= { "clk_pciephy1_osc0", "clk_pciephy1_div" };
+PNAME(clk_pciephy2_ref_p)		= { "clk_pciephy2_osc0", "clk_pciephy2_div" };
+PNAME(mux_gmac0_p)			= { "clk_mac0_2top", "gmac0_clkin" };
+PNAME(mux_gmac0_rgmii_speed_p)		= { "clk_gmac0", "clk_gmac0", "clk_gmac0_tx_div50", "clk_gmac0_tx_div5" };
+PNAME(mux_gmac0_rmii_speed_p)		= { "clk_gmac0_rx_div20", "clk_gmac0_rx_div2" };
+PNAME(mux_gmac0_rx_tx_p)		= { "clk_gmac0_rgmii_speed", "clk_gmac0_rmii_speed", "clk_gmac0_xpcs_mii" };
+PNAME(mux_gmac1_p)			= { "clk_mac1_2top", "gmac1_clkin" };
+PNAME(mux_gmac1_rgmii_speed_p)		= { "clk_gmac1", "clk_gmac1", "clk_gmac1_tx_div50", "clk_gmac1_tx_div5" };
+PNAME(mux_gmac1_rmii_speed_p)		= { "clk_gmac1_rx_div20", "clk_gmac1_rx_div2" };
+PNAME(mux_gmac1_rx_tx_p)		= { "clk_gmac1_rgmii_speed", "clk_gmac1_rmii_speed", "clk_gmac1_xpcs_mii" };
+PNAME(clk_hdmi_ref_p)			= { "hpll", "hpll_ph0" };
+PNAME(clk_pdpmu_p)			= { "ppll", "gpll" };
+PNAME(clk_mac_2top_p)			= { "cpll_125m", "cpll_50m", "cpll_25m", "ppll" };
+PNAME(clk_pwm0_p)			= { "xin24m", "clk_pdpmu" };
+PNAME(aclk_rkvdec_pre_p)		= { "gpll", "cpll" };
+PNAME(clk_rkvdec_core_p)		= { "gpll", "cpll", "dummy_npll", "dummy_vpll" };
+
+static struct rockchip_pll_clock rk3568_pmu_pll_clks[] __initdata = {
+	[ppll] = PLL(pll_rk3328, PLL_PPLL, "ppll",  mux_pll_p,
+		     0, RK3568_PMU_PLL_CON(0),
+		     RK3568_PMU_MODE_CON0, 0, 4, 0, rk3568_pll_rates),
+	[hpll] = PLL(pll_rk3328, PLL_HPLL, "hpll",  mux_pll_p,
+		     0, RK3568_PMU_PLL_CON(16),
+		     RK3568_PMU_MODE_CON0, 2, 7, 0, rk3568_pll_rates),
+};
+
+static struct rockchip_pll_clock rk3568_pll_clks[] __initdata = {
+	[apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
+		     0, RK3568_PLL_CON(0),
+		     RK3568_MODE_CON0, 0, 0, 0, rk3568_pll_rates),
+	[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
+		     0, RK3568_PLL_CON(8),
+		     RK3568_MODE_CON0, 2, 1, 0, NULL),
+	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+		     0, RK3568_PLL_CON(24),
+		     RK3568_MODE_CON0, 4, 2, 0, rk3568_pll_rates),
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     0, RK3568_PLL_CON(16),
+		     RK3568_MODE_CON0, 6, 3, 0, rk3568_pll_rates),
+	[npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p,
+		     0, RK3568_PLL_CON(32),
+		     RK3568_MODE_CON0, 10, 5, 0, rk3568_pll_rates),
+	[vpll] = PLL(pll_rk3328, PLL_VPLL, "vpll", mux_pll_p,
+		     0, RK3568_PLL_CON(40),
+		     RK3568_MODE_CON0, 12, 6, 0, rk3568_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rk3568_i2s0_8ch_tx_fracmux __initdata =
+	MUX(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(11), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s0_8ch_rx_fracmux __initdata =
+	MUX(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(13), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s1_8ch_tx_fracmux __initdata =
+	MUX(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(15), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s1_8ch_rx_fracmux __initdata =
+	MUX(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(17), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s2_2ch_fracmux __initdata =
+	MUX(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(19), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s3_2ch_tx_fracmux __initdata =
+	MUX(CLK_I2S3_2CH_TX, "clk_i2s3_2ch_tx", clk_i2s3_2ch_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(21), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_i2s3_2ch_rx_fracmux __initdata =
+	MUX(CLK_I2S3_2CH_RX, "clk_i2s3_2ch_rx", clk_i2s3_2ch_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(83), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_spdif_8ch_fracmux __initdata =
+	MUX(MCLK_SPDIF_8CH, "mclk_spdif_8ch", mclk_spdif_8ch_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(23), 15, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_audpwm_fracmux __initdata =
+	MUX(SCLK_AUDPWM, "sclk_audpwm", sclk_audpwm_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(25), 15, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart1_fracmux __initdata =
+	MUX(0, "sclk_uart1_mux", sclk_uart1_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(52), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart2_fracmux __initdata =
+	MUX(0, "sclk_uart2_mux", sclk_uart2_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(54), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart3_fracmux __initdata =
+	MUX(0, "sclk_uart3_mux", sclk_uart3_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(56), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart4_fracmux __initdata =
+	MUX(0, "sclk_uart4_mux", sclk_uart4_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(58), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart5_fracmux __initdata =
+	MUX(0, "sclk_uart5_mux", sclk_uart5_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(60), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart6_fracmux __initdata =
+	MUX(0, "sclk_uart6_mux", sclk_uart6_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(62), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart7_fracmux __initdata =
+	MUX(0, "sclk_uart7_mux", sclk_uart7_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(64), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart8_fracmux __initdata =
+	MUX(0, "sclk_uart8_mux", sclk_uart8_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(66), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart9_fracmux __initdata =
+	MUX(0, "sclk_uart9_mux", sclk_uart9_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(68), 12, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_uart0_fracmux __initdata =
+	MUX(0, "sclk_uart0_mux", sclk_uart0_p, CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(4), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_rtc32k_pmu_fracmux __initdata =
+	MUX(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3568_PMU_CLKSEL_CON(0), 6, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
+	/*
+	 * Clock-Architecture Diagram 1
+	 */
+	 /* SRC_CLK */
+	COMPOSITE_NOMUX(0, "gpll_400m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(75), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 0, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_300m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(75), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 1, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_200m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(76), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 2, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_150m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(76), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 3, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_100m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(77), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 4, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_75m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(77), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 5, GFLAGS),
+	COMPOSITE_NOMUX(0, "gpll_20m", "gpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(78), 0, 6, DFLAGS,
+			RK3568_CLKGATE_CON(35), 6, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_500M, "cpll_500m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(78), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 7, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_333M, "cpll_333m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(79), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 8, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_250M, "cpll_250m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(79), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 9, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(80), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 10, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(80), 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 11, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(81), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 12, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(81), 8, 6, DFLAGS,
+			RK3568_CLKGATE_CON(35), 13, GFLAGS),
+	COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(35), 14, GFLAGS),
+	COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(82), 8, 6, DFLAGS,
+			RK3568_CLKGATE_CON(35), 15, GFLAGS),
+	FACTOR(0, "clk_osc0_div_375k", "clk_osc0_div_750k", 0, 1, 2),
+	FACTOR(0, "xin_osc0_half", "xin24m", 0, 1, 2),
+	MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
+			RK3568_MODE_CON0, 14, 2, MFLAGS),
+
+	/* PD_CORE */
+	COMPOSITE(0, "sclk_core_src", apll_gpll_npll_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NODIV(0, "sclk_core", sclk_core_pre_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(2), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(0), 7, GFLAGS),
+
+	COMPOSITE_NOMUX(0, "atclk_core", "armclk", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(0, "gicclk_core", "armclk", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(4), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(0, "periphclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(4), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 11, GFLAGS),
+	COMPOSITE_NOMUX(0, "tsclk_core", "periphclk_core_pre", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(5), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_NOMUX(0, "cntclk_core", "periphclk_core_pre", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(5), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(0, "aclk_core", "sclk_core", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(5), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(1), 0, GFLAGS),
+
+	COMPOSITE_NODIV(ACLK_CORE_NIU2BUS, "aclk_core_niu2bus", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(5), 14, 2, MFLAGS,
+			RK3568_CLKGATE_CON(1), 2, GFLAGS),
+
+	GATE(CLK_CORE_PVTM, "clk_core_pvtm", "xin24m", 0,
+			RK3568_CLKGATE_CON(1), 10, GFLAGS),
+	GATE(CLK_CORE_PVTM_CORE, "clk_core_pvtm_core", "armclk", 0,
+			RK3568_CLKGATE_CON(1), 11, GFLAGS),
+	GATE(CLK_CORE_PVTPLL, "clk_core_pvtpll", "armclk", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_CORE_PVTM, "pclk_core_pvtm", "pclk_core_pre", 0,
+			RK3568_CLKGATE_CON(1), 9, GFLAGS),
+
+	/* PD_GPU */
+	COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", mpll_gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(6), 6, 2, MFLAGS | CLK_MUX_READ_ONLY, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3568_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_GPU_PRE_MUX, "clk_gpu_pre_mux", clk_gpu_pre_mux_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(6), 11, 1, MFLAGS | CLK_MUX_READ_ONLY),
+	DIV(ACLK_GPU_PRE, "aclk_gpu_pre", "clk_gpu_pre_mux", 0,
+			RK3568_CLKSEL_CON(6), 8, 2, DFLAGS),
+	DIV(PCLK_GPU_PRE, "pclk_gpu_pre", "clk_gpu_pre_mux", 0,
+			RK3568_CLKSEL_CON(6), 12, 4, DFLAGS),
+	GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre_mux", 0,
+			RK3568_CLKGATE_CON(2), 3, GFLAGS),
+
+	GATE(PCLK_GPU_PVTM, "pclk_gpu_pvtm", "pclk_gpu_pre", 0,
+			RK3568_CLKGATE_CON(2), 6, GFLAGS),
+	GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0,
+			RK3568_CLKGATE_CON(2), 7, GFLAGS),
+	GATE(CLK_GPU_PVTM_CORE, "clk_gpu_pvtm_core", "clk_gpu_src", 0,
+			RK3568_CLKGATE_CON(2), 8, GFLAGS),
+	GATE(CLK_GPU_PVTPLL, "clk_gpu_pvtpll", "clk_gpu_src", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(2), 9, GFLAGS),
+
+	/* PD_NPU */
+	COMPOSITE(CLK_NPU_SRC, "clk_npu_src", npll_gpll_p, 0,
+			RK3568_CLKSEL_CON(7), 6, 1, MFLAGS, 0, 4, DFLAGS,
+			RK3568_CLKGATE_CON(3), 0, GFLAGS),
+	MUX(CLK_NPU_PRE_NDFT, "clk_npu_pre_ndft", clk_npu_pre_ndft_p, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+			RK3568_CLKSEL_CON(7), 8, 1, MFLAGS),
+	MUX(CLK_NPU, "clk_npu", clk_npu_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(7), 15, 1, MFLAGS),
+	COMPOSITE_NOMUX(HCLK_NPU_PRE, "hclk_npu_pre", "clk_npu", 0,
+			RK3568_CLKSEL_CON(8), 0, 4, DFLAGS,
+			RK3568_CLKGATE_CON(3), 2, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_NPU_PRE, "pclk_npu_pre", "clk_npu", 0,
+			RK3568_CLKSEL_CON(8), 4, 4, DFLAGS,
+			RK3568_CLKGATE_CON(3), 3, GFLAGS),
+	GATE(ACLK_NPU_PRE, "aclk_npu_pre", "clk_npu", 0,
+			RK3568_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(ACLK_NPU, "aclk_npu", "aclk_npu_pre", 0,
+			RK3568_CLKGATE_CON(3), 7, GFLAGS),
+	GATE(HCLK_NPU, "hclk_npu", "hclk_npu_pre", 0,
+			RK3568_CLKGATE_CON(3), 8, GFLAGS),
+
+	GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_pre", 0,
+			RK3568_CLKGATE_CON(3), 9, GFLAGS),
+	GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0,
+			RK3568_CLKGATE_CON(3), 10, GFLAGS),
+	GATE(CLK_NPU_PVTM_CORE, "clk_npu_pvtm_core", "clk_npu_pre_ndft", 0,
+			RK3568_CLKGATE_CON(3), 11, GFLAGS),
+	GATE(CLK_NPU_PVTPLL, "clk_npu_pvtpll", "clk_npu_pre_ndft", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(3), 12, GFLAGS),
+
+	/* PD_DDR */
+	COMPOSITE(CLK_DDRPHY1X_SRC, "clk_ddrphy1x_src", dpll_gpll_cpll_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(4), 0, GFLAGS),
+	MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(9), 15, 1, MFLAGS),
+
+	COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
+			RK3568_CLKGATE_CON(4), 2, GFLAGS),
+	GATE(CLK24_DDRMON, "clk24_ddrmon", "xin24m", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(4), 15, GFLAGS),
+
+	/* PD_GIC_AUDIO */
+	COMPOSITE_NODIV(ACLK_GIC_AUDIO, "aclk_gic_audio", gpll200_gpll150_gpll100_xin24m_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(10), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE_NODIV(HCLK_GIC_AUDIO, "hclk_gic_audio", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(10), 10, 2, MFLAGS,
+			RK3568_CLKGATE_CON(5), 1, GFLAGS),
+	GATE(HCLK_SDMMC_BUFFER, "hclk_sdmmc_buffer", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 8, GFLAGS),
+	COMPOSITE_NODIV(DCLK_SDMMC_BUFFER, "dclk_sdmmc_buffer", gpll100_gpll75_gpll50_p, 0,
+			RK3568_CLKSEL_CON(10), 12, 2, MFLAGS,
+			RK3568_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(ACLK_GIC600, "aclk_gic600", "aclk_gic_audio", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(5), 4, GFLAGS),
+	GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_gic_audio", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 11, GFLAGS),
+	GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 13, GFLAGS),
+
+	COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(12), 0,
+			RK3568_CLKGATE_CON(6), 1, GFLAGS,
+			&rk3568_i2s0_8ch_tx_fracmux),
+	GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0,
+			RK3568_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(I2S0_MCLKOUT_TX, "i2s0_mclkout_tx", i2s0_mclkout_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(11), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(6), 3, GFLAGS),
+
+	COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(13), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(14), 0,
+			RK3568_CLKGATE_CON(6), 5, GFLAGS,
+			&rk3568_i2s0_8ch_rx_fracmux),
+	GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0,
+			RK3568_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(I2S0_MCLKOUT_RX, "i2s0_mclkout_rx", i2s0_mclkout_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(13), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(6), 7, GFLAGS),
+
+	COMPOSITE(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(15), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(6), 8, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(16), 0,
+			RK3568_CLKGATE_CON(6), 9, GFLAGS,
+			&rk3568_i2s1_8ch_tx_fracmux),
+	GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0,
+			RK3568_CLKGATE_CON(6), 10, GFLAGS),
+	COMPOSITE_NODIV(I2S1_MCLKOUT_TX, "i2s1_mclkout_tx", i2s1_mclkout_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(15), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(6), 11, GFLAGS),
+
+	COMPOSITE(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(6), 12, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(18), 0,
+			RK3568_CLKGATE_CON(6), 13, GFLAGS,
+			&rk3568_i2s1_8ch_rx_fracmux),
+	GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0,
+			RK3568_CLKGATE_CON(6), 14, GFLAGS),
+	COMPOSITE_NODIV(I2S1_MCLKOUT_RX, "i2s1_mclkout_rx", i2s1_mclkout_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(17), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(6), 15, GFLAGS),
+
+	COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(7), 0, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(20), 0,
+			RK3568_CLKGATE_CON(7), 1, GFLAGS,
+			&rk3568_i2s2_2ch_fracmux),
+	GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0,
+			RK3568_CLKGATE_CON(7), 2, GFLAGS),
+	COMPOSITE_NODIV(I2S2_MCLKOUT, "i2s2_mclkout", i2s2_mclkout_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(19), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(7), 3, GFLAGS),
+
+	COMPOSITE(CLK_I2S3_2CH_TX_SRC, "clk_i2s3_2ch_tx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(7), 4, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S3_2CH_TX_FRAC, "clk_i2s3_2ch_tx_frac", "clk_i2s3_2ch_tx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(22), 0,
+			RK3568_CLKGATE_CON(7), 5, GFLAGS,
+			&rk3568_i2s3_2ch_tx_fracmux),
+	GATE(MCLK_I2S3_2CH_TX, "mclk_i2s3_2ch_tx", "clk_i2s3_2ch_tx", 0,
+			RK3568_CLKGATE_CON(7), 6, GFLAGS),
+	COMPOSITE_NODIV(I2S3_MCLKOUT_TX, "i2s3_mclkout_tx", i2s3_mclkout_tx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(21), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(7), 7, GFLAGS),
+
+	COMPOSITE(CLK_I2S3_2CH_RX_SRC, "clk_i2s3_2ch_rx_src", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(83), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(7), 8, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_I2S3_2CH_RX_FRAC, "clk_i2s3_2ch_rx_frac", "clk_i2s3_2ch_rx_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(84), 0,
+			RK3568_CLKGATE_CON(7), 9, GFLAGS,
+			&rk3568_i2s3_2ch_rx_fracmux),
+	GATE(MCLK_I2S3_2CH_RX, "mclk_i2s3_2ch_rx", "clk_i2s3_2ch_rx", 0,
+			RK3568_CLKGATE_CON(7), 10, GFLAGS),
+	COMPOSITE_NODIV(I2S3_MCLKOUT_RX, "i2s3_mclkout_rx", i2s3_mclkout_rx_p, CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(83), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(7), 11, GFLAGS),
+
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(5), 14, GFLAGS),
+	COMPOSITE_NODIV(MCLK_PDM, "mclk_pdm", mclk_pdm_p, 0,
+			RK3568_CLKSEL_CON(23), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_VAD, "hclk_vad", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(7), 12, GFLAGS),
+	GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(7), 13, GFLAGS),
+
+	COMPOSITE(MCLK_SPDIF_8CH_SRC, "mclk_spdif_8ch_src", cpll_gpll_p, 0,
+			RK3568_CLKSEL_CON(23), 14, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(7), 14, GFLAGS),
+	COMPOSITE_FRACMUX(MCLK_SPDIF_8CH_FRAC, "mclk_spdif_8ch_frac", "mclk_spdif_8ch_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(24), 0,
+			RK3568_CLKGATE_CON(7), 15, GFLAGS,
+			&rk3568_spdif_8ch_fracmux),
+
+	GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(8), 0, GFLAGS),
+	COMPOSITE(SCLK_AUDPWM_SRC, "sclk_audpwm_src", gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(25), 14, 1, MFLAGS, 0, 6, DFLAGS,
+			RK3568_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_FRACMUX(SCLK_AUDPWM_FRAC, "sclk_audpwm_frac", "sclk_audpwm_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(26), 0,
+			RK3568_CLKGATE_CON(8), 2, GFLAGS,
+			&rk3568_audpwm_fracmux),
+
+	GATE(HCLK_ACDCDIG, "hclk_acdcdig", "hclk_gic_audio", 0,
+			RK3568_CLKGATE_CON(8), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", clk_i2c_p, 0,
+			RK3568_CLKSEL_CON(23), 10, 2, MFLAGS,
+			RK3568_CLKGATE_CON(8), 4, GFLAGS),
+	GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s3_2ch_tx", 0,
+			RK3568_CLKGATE_CON(8), 5, GFLAGS),
+	GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s3_2ch_rx", 0,
+			RK3568_CLKGATE_CON(8), 6, GFLAGS),
+
+	/* PD_SECURE_FLASH */
+	COMPOSITE_NODIV(ACLK_SECURE_FLASH, "aclk_secure_flash", gpll200_gpll150_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(27), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(8), 7, GFLAGS),
+	COMPOSITE_NODIV(HCLK_SECURE_FLASH, "hclk_secure_flash", gpll150_gpll100_gpll75_xin24m_p, 0,
+			RK3568_CLKSEL_CON(27), 2, 2, MFLAGS,
+			RK3568_CLKGATE_CON(8), 8, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(8), 11, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(8), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_CRYPTO_NS_CORE, "clk_crypto_ns_core", gpll200_gpll150_gpll100_p, 0,
+			RK3568_CLKSEL_CON(27), 4, 2, MFLAGS,
+			RK3568_CLKGATE_CON(8), 13, GFLAGS),
+	COMPOSITE_NODIV(CLK_CRYPTO_NS_PKA, "clk_crypto_ns_pka", gpll300_gpll200_gpll100_p, 0,
+			RK3568_CLKSEL_CON(27), 6, 2, MFLAGS,
+			RK3568_CLKGATE_CON(8), 14, GFLAGS),
+	GATE(CLK_CRYPTO_NS_RNG, "clk_crypto_ns_rng", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(8), 15, GFLAGS),
+	GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_flash", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(9), 10, GFLAGS),
+	GATE(CLK_TRNG_NS, "clk_trng_ns", "hclk_secure_flash", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(9), 11, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(26), 9, GFLAGS),
+	GATE(CLK_OTPC_NS_SBPI, "clk_otpc_ns_sbpi", "xin24m", 0,
+			RK3568_CLKGATE_CON(26), 10, GFLAGS),
+	GATE(CLK_OTPC_NS_USR, "clk_otpc_ns_usr", "xin_osc0_half", 0,
+			RK3568_CLKGATE_CON(26), 11, GFLAGS),
+	GATE(HCLK_NANDC, "hclk_nandc", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(9), 0, GFLAGS),
+	COMPOSITE_NODIV(NCLK_NANDC, "nclk_nandc", clk_nandc_p, 0,
+			RK3568_CLKSEL_CON(28), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(9), 1, GFLAGS),
+	GATE(HCLK_SFC, "hclk_sfc", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(9), 2, GFLAGS),
+	GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(9), 3, GFLAGS),
+	COMPOSITE_NODIV(SCLK_SFC, "sclk_sfc", sclk_sfc_p, 0,
+			RK3568_CLKSEL_CON(28), 4, 3, MFLAGS,
+			RK3568_CLKGATE_CON(9), 4, GFLAGS),
+	GATE(ACLK_EMMC, "aclk_emmc", "aclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(9), 5, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "hclk_secure_flash", 0,
+			RK3568_CLKGATE_CON(9), 6, GFLAGS),
+	COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", gpll200_gpll150_cpll125_p, 0,
+			RK3568_CLKSEL_CON(28), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(9), 7, GFLAGS),
+	COMPOSITE_NODIV(CCLK_EMMC, "cclk_emmc", cclk_emmc_p, 0,
+			RK3568_CLKSEL_CON(28), 12, 3, MFLAGS,
+			RK3568_CLKGATE_CON(9), 8, GFLAGS),
+	GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0,
+			RK3568_CLKGATE_CON(9), 9, GFLAGS),
+	MMC(SCLK_EMMC_DRV, "emmc_drv", "cclk_emmc", RK3568_EMMC_CON0, 1),
+	MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "cclk_emmc", RK3568_EMMC_CON1, 1),
+
+	/* PD_PIPE */
+	COMPOSITE_NODIV(ACLK_PIPE, "aclk_pipe", aclk_pipe_p, 0,
+			RK3568_CLKSEL_CON(29), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(10), 0, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_PIPE, "pclk_pipe", "aclk_pipe", 0,
+			RK3568_CLKSEL_CON(29), 4, 4, DFLAGS,
+			RK3568_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 0, GFLAGS),
+	GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 2, GFLAGS),
+	GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 0,
+			RK3568_CLKGATE_CON(12), 4, GFLAGS),
+	GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 8, GFLAGS),
+	GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(ACLK_PCIE30X1_DBI, "aclk_pcie30x1_dbi", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 10, GFLAGS),
+	GATE(PCLK_PCIE30X1, "pclk_pcie30x1", "pclk_pipe", 0,
+			RK3568_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 0,
+			RK3568_CLKGATE_CON(12), 12, GFLAGS),
+	GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(13), 0, GFLAGS),
+	GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(ACLK_PCIE30X2_DBI, "aclk_pcie30x2_dbi", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(13), 2, GFLAGS),
+	GATE(PCLK_PCIE30X2, "pclk_pcie30x2", "pclk_pipe", 0,
+			RK3568_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 0,
+			RK3568_CLKGATE_CON(13), 4, GFLAGS),
+	GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "gpll_20m", 0,
+			RK3568_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(CLK_SATA0_RXOOB, "clk_sata0_rxoob", "cpll_50m", 0,
+			RK3568_CLKGATE_CON(11), 2, GFLAGS),
+	GATE(ACLK_SATA1, "aclk_sata1", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(CLK_SATA1_PMALIVE, "clk_sata1_pmalive", "gpll_20m", 0,
+			RK3568_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(CLK_SATA1_RXOOB, "clk_sata1_rxoob", "cpll_50m", 0,
+			RK3568_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(ACLK_SATA2, "aclk_sata2", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(11), 8, GFLAGS),
+	GATE(CLK_SATA2_PMALIVE, "clk_sata2_pmalive", "gpll_20m", 0,
+			RK3568_CLKGATE_CON(11), 9, GFLAGS),
+	GATE(CLK_SATA2_RXOOB, "clk_sata2_rxoob", "cpll_50m", 0,
+			RK3568_CLKGATE_CON(11), 10, GFLAGS),
+	GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(10), 8, GFLAGS),
+	GATE(CLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0,
+			RK3568_CLKGATE_CON(10), 9, GFLAGS),
+	COMPOSITE_NODIV(CLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", xin24m_32k_p, 0,
+			RK3568_CLKSEL_CON(29), 8, 1, MFLAGS,
+			RK3568_CLKGATE_CON(10), 10, GFLAGS),
+	GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_pipe", 0,
+			RK3568_CLKGATE_CON(10), 12, GFLAGS),
+	GATE(CLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0,
+			RK3568_CLKGATE_CON(10), 13, GFLAGS),
+	COMPOSITE_NODIV(CLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", xin24m_32k_p, 0,
+			RK3568_CLKSEL_CON(29), 9, 1, MFLAGS,
+			RK3568_CLKGATE_CON(10), 14, GFLAGS),
+	COMPOSITE_NODIV(CLK_XPCS_EEE, "clk_xpcs_eee", gpll200_cpll125_p, 0,
+			RK3568_CLKSEL_CON(29), 13, 1, MFLAGS,
+			RK3568_CLKGATE_CON(10), 4, GFLAGS),
+	GATE(PCLK_XPCS, "pclk_xpcs", "pclk_pipe", 0,
+			RK3568_CLKGATE_CON(13), 6, GFLAGS),
+
+	/* PD_PHP */
+	COMPOSITE_NODIV(ACLK_PHP, "aclk_php", gpll300_gpll200_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(30), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(14), 8, GFLAGS),
+	COMPOSITE_NODIV(HCLK_PHP, "hclk_php", gpll150_gpll100_gpll75_xin24m_p, 0,
+			RK3568_CLKSEL_CON(30), 2, 2, MFLAGS,
+			RK3568_CLKGATE_CON(14), 9, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_PHP, "pclk_php", "aclk_php", 0,
+			RK3568_CLKSEL_CON(30), 4, 4, DFLAGS,
+			RK3568_CLKGATE_CON(14), 10, GFLAGS),
+	GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_php", 0,
+			RK3568_CLKGATE_CON(15), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_SDMMC0, "clk_sdmmc0", clk_sdmmc_p, 0,
+			RK3568_CLKSEL_CON(30), 8, 3, MFLAGS,
+			RK3568_CLKGATE_CON(15), 1, GFLAGS),
+	MMC(SCLK_SDMMC0_DRV, "sdmmc0_drv", "clk_sdmmc0", RK3568_SDMMC0_CON0, 1),
+	MMC(SCLK_SDMMC0_SAMPLE, "sdmmc0_sample", "clk_sdmmc0", RK3568_SDMMC0_CON1, 1),
+
+	GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_php", 0,
+			RK3568_CLKGATE_CON(15), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_SDMMC1, "clk_sdmmc1", clk_sdmmc_p, 0,
+			RK3568_CLKSEL_CON(30), 12, 3, MFLAGS,
+			RK3568_CLKGATE_CON(15), 3, GFLAGS),
+	MMC(SCLK_SDMMC1_DRV, "sdmmc1_drv", "clk_sdmmc1", RK3568_SDMMC1_CON0, 1),
+	MMC(SCLK_SDMMC1_SAMPLE, "sdmmc1_sample", "clk_sdmmc1", RK3568_SDMMC1_CON1, 1),
+
+	GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_php", 0,
+			RK3568_CLKGATE_CON(15), 5, GFLAGS),
+	GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php", 0,
+			RK3568_CLKGATE_CON(15), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_MAC0_2TOP, "clk_mac0_2top", clk_mac_2top_p, 0,
+			RK3568_CLKSEL_CON(31), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(15), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_MAC0_OUT, "clk_mac0_out", cpll125_cpll50_cpll25_xin24m_p, 0,
+			RK3568_CLKSEL_CON(31), 14, 2, MFLAGS,
+			RK3568_CLKGATE_CON(15), 8, GFLAGS),
+	GATE(CLK_MAC0_REFOUT, "clk_mac0_refout", "clk_mac0_2top", 0,
+			RK3568_CLKGATE_CON(15), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac_ptp_p, 0,
+			RK3568_CLKSEL_CON(31), 12, 2, MFLAGS,
+			RK3568_CLKGATE_CON(15), 4, GFLAGS),
+	MUX(SCLK_GMAC0, "clk_gmac0", mux_gmac0_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(31), 2, 1, MFLAGS),
+	FACTOR(0, "clk_gmac0_tx_div5", "clk_gmac0", 0, 1, 5),
+	FACTOR(0, "clk_gmac0_tx_div50", "clk_gmac0", 0, 1, 50),
+	FACTOR(0, "clk_gmac0_rx_div2", "clk_gmac0", 0, 1, 2),
+	FACTOR(0, "clk_gmac0_rx_div20", "clk_gmac0", 0, 1, 20),
+	MUX(SCLK_GMAC0_RGMII_SPEED, "clk_gmac0_rgmii_speed", mux_gmac0_rgmii_speed_p, 0,
+			RK3568_CLKSEL_CON(31), 4, 2, MFLAGS),
+	MUX(SCLK_GMAC0_RMII_SPEED, "clk_gmac0_rmii_speed", mux_gmac0_rmii_speed_p, 0,
+			RK3568_CLKSEL_CON(31), 3, 1, MFLAGS),
+	MUX(SCLK_GMAC0_RX_TX, "clk_gmac0_rx_tx", mux_gmac0_rx_tx_p,  CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(31), 0, 2, MFLAGS),
+
+	/* PD_USB */
+	COMPOSITE_NODIV(ACLK_USB, "aclk_usb", gpll300_gpll200_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(32), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(HCLK_USB, "hclk_usb", gpll150_gpll100_gpll75_xin24m_p, 0,
+			RK3568_CLKSEL_CON(32), 2, 2, MFLAGS,
+			RK3568_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_USB, "pclk_usb", "aclk_usb", 0,
+			RK3568_CLKSEL_CON(32), 4, 4, DFLAGS,
+			RK3568_CLKGATE_CON(16), 2, GFLAGS),
+	GATE(HCLK_USB2HOST0, "hclk_usb2host0", "hclk_usb", 0,
+			RK3568_CLKGATE_CON(16), 12, GFLAGS),
+	GATE(HCLK_USB2HOST0_ARB, "hclk_usb2host0_arb", "hclk_usb", 0,
+			RK3568_CLKGATE_CON(16), 13, GFLAGS),
+	GATE(HCLK_USB2HOST1, "hclk_usb2host1", "hclk_usb", 0,
+			RK3568_CLKGATE_CON(16), 14, GFLAGS),
+	GATE(HCLK_USB2HOST1_ARB, "hclk_usb2host1_arb", "hclk_usb", 0,
+			RK3568_CLKGATE_CON(16), 15, GFLAGS),
+	GATE(HCLK_SDMMC2, "hclk_sdmmc2", "hclk_usb", 0,
+			RK3568_CLKGATE_CON(17), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_SDMMC2, "clk_sdmmc2", clk_sdmmc_p, 0,
+			RK3568_CLKSEL_CON(32), 8, 3, MFLAGS,
+			RK3568_CLKGATE_CON(17), 1, GFLAGS),
+	MMC(SCLK_SDMMC2_DRV, "sdmmc2_drv", "clk_sdmmc2", RK3568_SDMMC2_CON0, 1),
+	MMC(SCLK_SDMMC2_SAMPLE, "sdmmc2_sample", "clk_sdmmc2", RK3568_SDMMC2_CON1, 1),
+
+	GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_usb", 0,
+			RK3568_CLKGATE_CON(17), 3, GFLAGS),
+	GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_usb", 0,
+			RK3568_CLKGATE_CON(17), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_MAC1_2TOP, "clk_mac1_2top", clk_mac_2top_p, 0,
+			RK3568_CLKSEL_CON(33), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(17), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_MAC1_OUT, "clk_mac1_out", cpll125_cpll50_cpll25_xin24m_p, 0,
+			RK3568_CLKSEL_CON(33), 14, 2, MFLAGS,
+			RK3568_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(CLK_MAC1_REFOUT, "clk_mac1_refout", "clk_mac1_2top", 0,
+			RK3568_CLKGATE_CON(17), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac_ptp_p, 0,
+			RK3568_CLKSEL_CON(33), 12, 2, MFLAGS,
+			RK3568_CLKGATE_CON(17), 2, GFLAGS),
+	MUX(SCLK_GMAC1, "clk_gmac1", mux_gmac1_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(33), 2, 1, MFLAGS),
+	FACTOR(0, "clk_gmac1_tx_div5", "clk_gmac1", 0, 1, 5),
+	FACTOR(0, "clk_gmac1_tx_div50", "clk_gmac1", 0, 1, 50),
+	FACTOR(0, "clk_gmac1_rx_div2", "clk_gmac1", 0, 1, 2),
+	FACTOR(0, "clk_gmac1_rx_div20", "clk_gmac1", 0, 1, 20),
+	MUX(SCLK_GMAC1_RGMII_SPEED, "clk_gmac1_rgmii_speed", mux_gmac1_rgmii_speed_p, 0,
+			RK3568_CLKSEL_CON(33), 4, 2, MFLAGS),
+	MUX(SCLK_GMAC1_RMII_SPEED, "clk_gmac1_rmii_speed", mux_gmac1_rmii_speed_p, 0,
+			RK3568_CLKSEL_CON(33), 3, 1, MFLAGS),
+	MUX(SCLK_GMAC1_RX_TX, "clk_gmac1_rx_tx", mux_gmac1_rx_tx_p,  CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(33), 0, 2, MFLAGS),
+
+	/* PD_PERI */
+	COMPOSITE_NODIV(ACLK_PERIMID, "aclk_perimid", gpll300_gpll200_gpll100_xin24m_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(10), 4, 2, MFLAGS,
+			RK3568_CLKGATE_CON(14), 0, GFLAGS),
+	COMPOSITE_NODIV(HCLK_PERIMID, "hclk_perimid", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
+			RK3568_CLKSEL_CON(10), 6, 2, MFLAGS,
+			RK3568_CLKGATE_CON(14), 1, GFLAGS),
+
+	/* PD_VI */
+	COMPOSITE_NODIV(ACLK_VI, "aclk_vi", gpll400_gpll300_gpll200_xin24m_p, 0,
+			RK3568_CLKSEL_CON(34), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(18), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VI, "hclk_vi", "aclk_vi", 0,
+			RK3568_CLKSEL_CON(34), 4, 4, DFLAGS,
+			RK3568_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_VI, "pclk_vi", "aclk_vi", 0,
+			RK3568_CLKSEL_CON(34), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi", 0,
+			RK3568_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 0,
+			RK3568_CLKGATE_CON(18), 10, GFLAGS),
+	COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", cpll333_gpll300_gpll200_p, 0,
+			RK3568_CLKSEL_CON(34), 14, 2, MFLAGS,
+			RK3568_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(ICLK_VICAP_G, "iclk_vicap_g", "iclk_vicap", 0,
+			RK3568_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(ACLK_ISP, "aclk_isp", "aclk_vi", 0,
+			RK3568_CLKGATE_CON(19), 0, GFLAGS),
+	GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 0,
+			RK3568_CLKGATE_CON(19), 1, GFLAGS),
+	COMPOSITE(CLK_ISP, "clk_isp", cpll_gpll_hpll_p, 0,
+			RK3568_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(19), 2, GFLAGS),
+	GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi", 0,
+			RK3568_CLKGATE_CON(19), 4, GFLAGS),
+	COMPOSITE(CLK_CIF_OUT, "clk_cif_out", gpll_usb480m_xin24m_p, 0,
+			RK3568_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3568_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_CAM0_OUT, "clk_cam0_out", gpll_usb480m_xin24m_p, 0,
+			RK3568_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3568_CLKGATE_CON(19), 9, GFLAGS),
+	COMPOSITE(CLK_CAM1_OUT, "clk_cam1_out", gpll_usb480m_xin24m_p, 0,
+			RK3568_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3568_CLKGATE_CON(19), 10, GFLAGS),
+
+	/* PD_VO */
+	COMPOSITE_NODIV(ACLK_VO, "aclk_vo", gpll300_cpll250_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(37), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(20), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VO, "hclk_vo", "aclk_vo", 0,
+			RK3568_CLKSEL_CON(37), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(20), 1, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_VO, "pclk_vo", "aclk_vo", 0,
+			RK3568_CLKSEL_CON(37), 12, 4, DFLAGS,
+			RK3568_CLKGATE_CON(20), 2, GFLAGS),
+	COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", cpll_gpll_hpll_vpll_p, 0,
+			RK3568_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(20), 6, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0,
+			RK3568_CLKGATE_CON(20), 8, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
+			RK3568_CLKGATE_CON(20), 9, GFLAGS),
+	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3568_CLKGATE_CON(20), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3568_CLKGATE_CON(20), 11, GFLAGS),
+	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
+			RK3568_CLKGATE_CON(20), 12, GFLAGS),
+	GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
+			RK3568_CLKGATE_CON(20), 13, GFLAGS),
+	GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 0, GFLAGS),
+	GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(PCLK_HDMI_HOST, "pclk_hdmi_host", "pclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 3, GFLAGS),
+	GATE(CLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0,
+			RK3568_CLKGATE_CON(21), 4, GFLAGS),
+	GATE(CLK_HDMI_CEC, "clk_hdmi_cec", "clk_rtc_32k", 0,
+			RK3568_CLKGATE_CON(21), 5, GFLAGS),
+	GATE(PCLK_DSITX_0, "pclk_dsitx_0", "pclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(PCLK_DSITX_1, "pclk_dsitx_1", "pclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 7, GFLAGS),
+	GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_vo", 0,
+			RK3568_CLKGATE_CON(21), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_EDP_200M, "clk_edp_200m", gpll200_gpll150_cpll125_p, 0,
+			RK3568_CLKSEL_CON(38), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(21), 9, GFLAGS),
+
+	/* PD_VPU */
+	COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(42), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(22), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0,
+			RK3568_CLKSEL_CON(42), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(22), 1, GFLAGS),
+	GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0,
+			RK3568_CLKGATE_CON(22), 4, GFLAGS),
+	GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0,
+			RK3568_CLKGATE_CON(22), 5, GFLAGS),
+
+	/* PD_RGA */
+	COMPOSITE_NODIV(ACLK_RGA_PRE, "aclk_rga_pre", gpll300_cpll250_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(43), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(23), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_RGA_PRE, "hclk_rga_pre", "aclk_rga_pre", 0,
+			RK3568_CLKSEL_CON(43), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(23), 1, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_RGA_PRE, "pclk_rga_pre", "aclk_rga_pre", 0,
+			RK3568_CLKSEL_CON(43), 12, 4, DFLAGS,
+			RK3568_CLKGATE_CON(22), 12, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 4, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_RGA_CORE, "clk_rga_core", gpll300_gpll200_gpll100_p, 0,
+			RK3568_CLKSEL_CON(43), 2, 2, MFLAGS,
+			RK3568_CLKGATE_CON(23), 6, GFLAGS),
+	GATE(ACLK_IEP, "aclk_iep", "aclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 7, GFLAGS),
+	GATE(HCLK_IEP, "hclk_iep", "hclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_IEP_CORE, "clk_iep_core", gpll300_gpll200_gpll100_p, 0,
+			RK3568_CLKSEL_CON(43), 4, 2, MFLAGS,
+			RK3568_CLKGATE_CON(23), 9, GFLAGS),
+	GATE(HCLK_EBC, "hclk_ebc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 10, GFLAGS),
+	COMPOSITE_NODIV(DCLK_EBC, "dclk_ebc", gpll400_cpll333_gpll200_p, 0,
+			RK3568_CLKSEL_CON(43), 6, 2, MFLAGS,
+			RK3568_CLKGATE_CON(23), 11, GFLAGS),
+	GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 12, GFLAGS),
+	GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 13, GFLAGS),
+	GATE(ACLK_JENC, "aclk_jenc", "aclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 14, GFLAGS),
+	GATE(HCLK_JENC, "hclk_jenc", "hclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(23), 15, GFLAGS),
+	GATE(PCLK_EINK, "pclk_eink", "pclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(22), 14, GFLAGS),
+	GATE(HCLK_EINK, "hclk_eink", "hclk_rga_pre", 0,
+			RK3568_CLKGATE_CON(22), 15, GFLAGS),
+
+	/* PD_RKVENC */
+	COMPOSITE(ACLK_RKVENC_PRE, "aclk_rkvenc_pre", gpll_cpll_npll_p, 0,
+			RK3568_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(24), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_RKVENC_PRE, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0,
+			RK3568_CLKSEL_CON(44), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(24), 1, GFLAGS),
+	GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0,
+			RK3568_CLKGATE_CON(24), 6, GFLAGS),
+	GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0,
+			RK3568_CLKGATE_CON(24), 7, GFLAGS),
+	COMPOSITE(CLK_RKVENC_CORE, "clk_rkvenc_core", gpll_cpll_npll_vpll_p, 0,
+			RK3568_CLKSEL_CON(45), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(24), 8, GFLAGS),
+	COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", aclk_rkvdec_pre_p, CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(47), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(25), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0,
+			RK3568_CLKSEL_CON(47), 8, 4, DFLAGS,
+			RK3568_CLKGATE_CON(25), 1, GFLAGS),
+	GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0,
+			RK3568_CLKGATE_CON(25), 4, GFLAGS),
+	GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0,
+			RK3568_CLKGATE_CON(25), 5, GFLAGS),
+	COMPOSITE(CLK_RKVDEC_CA, "clk_rkvdec_ca", gpll_cpll_npll_vpll_p, 0,
+			RK3568_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(25), 6, GFLAGS),
+	COMPOSITE(CLK_RKVDEC_CORE, "clk_rkvdec_core", clk_rkvdec_core_p, CLK_SET_RATE_NO_REPARENT,
+			RK3568_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(25), 7, GFLAGS),
+	COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_npll_vpll_p, 0,
+			RK3568_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(25), 8, GFLAGS),
+
+	/* PD_BUS */
+	COMPOSITE_NODIV(ACLK_BUS, "aclk_bus", gpll200_gpll150_gpll100_xin24m_p, 0,
+			RK3568_CLKSEL_CON(50), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(26), 0, GFLAGS),
+	COMPOSITE_NODIV(PCLK_BUS, "pclk_bus", gpll100_gpll75_cpll50_xin24m_p, 0,
+			RK3568_CLKSEL_CON(50), 4, 2, MFLAGS,
+			RK3568_CLKGATE_CON(26), 1, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(26), 4, GFLAGS),
+	COMPOSITE(CLK_TSADC_TSEN, "clk_tsadc_tsen", xin24m_gpll100_cpll100_p, 0,
+			RK3568_CLKSEL_CON(51), 4, 2, MFLAGS, 0, 3, DFLAGS,
+			RK3568_CLKGATE_CON(26), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "clk_tsadc_tsen", 0,
+			RK3568_CLKSEL_CON(51), 8, 7, DFLAGS,
+			RK3568_CLKGATE_CON(26), 6, GFLAGS),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(26), 7, GFLAGS),
+	GATE(CLK_SARADC, "clk_saradc", "xin24m", 0,
+			RK3568_CLKGATE_CON(26), 8, GFLAGS),
+	GATE(PCLK_SCR, "pclk_scr", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(26), 12, GFLAGS),
+	GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(26), 13, GFLAGS),
+	GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0,
+			RK3568_CLKGATE_CON(26), 14, GFLAGS),
+	GATE(ACLK_MCU, "aclk_mcu", "aclk_bus", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(32), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus", CLK_IGNORE_UNUSED,
+			RK3568_CLKGATE_CON(32), 14, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(32), 15, GFLAGS),
+
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(27), 12, GFLAGS),
+	COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(27), 13, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(53), 0,
+			RK3568_CLKGATE_CON(27), 14, GFLAGS,
+			&rk3568_uart1_fracmux),
+	GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_mux", 0,
+			RK3568_CLKGATE_CON(27), 15, GFLAGS),
+
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(28), 0, GFLAGS),
+	COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(28), 1, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(55), 0,
+			RK3568_CLKGATE_CON(28), 2, GFLAGS,
+			&rk3568_uart2_fracmux),
+	GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_mux", 0,
+			RK3568_CLKGATE_CON(28), 3, GFLAGS),
+
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(28), 4, GFLAGS),
+	COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(28), 5, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(57), 0,
+			RK3568_CLKGATE_CON(28), 6, GFLAGS,
+			&rk3568_uart3_fracmux),
+	GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_mux", 0,
+			RK3568_CLKGATE_CON(28), 7, GFLAGS),
+
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(28), 8, GFLAGS),
+	COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(28), 9, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(59), 0,
+			RK3568_CLKGATE_CON(28), 10, GFLAGS,
+			&rk3568_uart4_fracmux),
+	GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_mux", 0,
+			RK3568_CLKGATE_CON(28), 11, GFLAGS),
+
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(28), 12, GFLAGS),
+	COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(28), 13, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(61), 0,
+			RK3568_CLKGATE_CON(28), 14, GFLAGS,
+			&rk3568_uart5_fracmux),
+	GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_mux", 0,
+			RK3568_CLKGATE_CON(28), 15, GFLAGS),
+
+	GATE(PCLK_UART6, "pclk_uart6", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(29), 0, GFLAGS),
+	COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(29), 1, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(63), 0,
+			RK3568_CLKGATE_CON(29), 2, GFLAGS,
+			&rk3568_uart6_fracmux),
+	GATE(SCLK_UART6, "sclk_uart6", "sclk_uart6_mux", 0,
+			RK3568_CLKGATE_CON(29), 3, GFLAGS),
+
+	GATE(PCLK_UART7, "pclk_uart7", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(29), 4, GFLAGS),
+	COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(29), 5, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(65), 0,
+			RK3568_CLKGATE_CON(29), 6, GFLAGS,
+			&rk3568_uart7_fracmux),
+	GATE(SCLK_UART7, "sclk_uart7", "sclk_uart7_mux", 0,
+			RK3568_CLKGATE_CON(29), 7, GFLAGS),
+
+	GATE(PCLK_UART8, "pclk_uart8", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(29), 8, GFLAGS),
+	COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(29), 9, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(67), 0,
+			RK3568_CLKGATE_CON(29), 10, GFLAGS,
+			&rk3568_uart8_fracmux),
+	GATE(SCLK_UART8, "sclk_uart8", "sclk_uart8_mux", 0,
+			RK3568_CLKGATE_CON(29), 11, GFLAGS),
+
+	GATE(PCLK_UART9, "pclk_uart9", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(29), 12, GFLAGS),
+	COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_usb480m_p, 0,
+			RK3568_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_CLKGATE_CON(29), 13, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", CLK_SET_RATE_PARENT,
+			RK3568_CLKSEL_CON(69), 0,
+			RK3568_CLKGATE_CON(29), 14, GFLAGS,
+			&rk3568_uart9_fracmux),
+	GATE(SCLK_UART9, "sclk_uart9", "sclk_uart9_mux", 0,
+			RK3568_CLKGATE_CON(29), 15, GFLAGS),
+
+	GATE(PCLK_CAN0, "pclk_can0", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(27), 5, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(70), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(27), 6, GFLAGS),
+	GATE(PCLK_CAN1, "pclk_can1", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(27), 7, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(70), 15, 1, MFLAGS, 8, 5, DFLAGS,
+			RK3568_CLKGATE_CON(27), 8, GFLAGS),
+	GATE(PCLK_CAN2, "pclk_can2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(27), 9, GFLAGS),
+	COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0,
+			RK3568_CLKSEL_CON(71), 7, 1, MFLAGS, 0, 5, DFLAGS,
+			RK3568_CLKGATE_CON(27), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_I2C, "clk_i2c", clk_i2c_p, 0,
+			RK3568_CLKSEL_CON(71), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(32), 10, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 0, GFLAGS),
+	GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 0,
+			RK3568_CLKGATE_CON(30), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 2, GFLAGS),
+	GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 0,
+			RK3568_CLKGATE_CON(30), 3, GFLAGS),
+	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 4, GFLAGS),
+	GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 0,
+			RK3568_CLKGATE_CON(30), 5, GFLAGS),
+	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 6, GFLAGS),
+	GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 0,
+			RK3568_CLKGATE_CON(30), 7, GFLAGS),
+	GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 8, GFLAGS),
+	GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 0,
+			RK3568_CLKGATE_CON(30), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", gpll200_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 0, 1, MFLAGS,
+			RK3568_CLKGATE_CON(30), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", gpll200_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 2, 1, MFLAGS,
+			RK3568_CLKGATE_CON(30), 13, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(30), 14, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", gpll200_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 4, 1, MFLAGS,
+			RK3568_CLKGATE_CON(30), 15, GFLAGS),
+	GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", gpll200_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 6, 1, MFLAGS, RK3568_CLKGATE_CON(31), 1, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", gpll100_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 8, 1, MFLAGS,
+			RK3568_CLKGATE_CON(31), 11, GFLAGS),
+	GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0,
+			RK3568_CLKGATE_CON(31), 12, GFLAGS),
+	GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 13, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", gpll100_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 10, 1, MFLAGS,
+			RK3568_CLKGATE_CON(31), 14, GFLAGS),
+	GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0,
+			RK3568_CLKGATE_CON(31), 15, GFLAGS),
+	GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(32), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", gpll100_xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(72), 12, 1, MFLAGS,
+			RK3568_CLKGATE_CON(32), 1, GFLAGS),
+	GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO, "dbclk_gpio", xin24m_32k_p, 0,
+			RK3568_CLKSEL_CON(72), 14, 1, MFLAGS,
+			RK3568_CLKGATE_CON(32), 11, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 2, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "dbclk_gpio", 0,
+			RK3568_CLKGATE_CON(31), 3, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 4, GFLAGS),
+	GATE(DBCLK_GPIO2, "dbclk_gpio2", "dbclk_gpio", 0,
+			RK3568_CLKGATE_CON(31), 5, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 6, GFLAGS),
+	GATE(DBCLK_GPIO3, "dbclk_gpio3", "dbclk_gpio", 0,
+			RK3568_CLKGATE_CON(31), 7, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(31), 8, GFLAGS),
+	GATE(DBCLK_GPIO4, "dbclk_gpio4", "dbclk_gpio", 0,
+			RK3568_CLKGATE_CON(31), 9, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0,
+			RK3568_CLKGATE_CON(32), 3, GFLAGS),
+	GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 4, GFLAGS),
+	GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 5, GFLAGS),
+	GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 6, GFLAGS),
+	GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 7, GFLAGS),
+	GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 8, GFLAGS),
+	GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0,
+			RK3568_CLKGATE_CON(32), 9, GFLAGS),
+
+	/* PD_TOP */
+	COMPOSITE_NODIV(ACLK_TOP_HIGH, "aclk_top_high", cpll500_gpll400_gpll300_xin24m_p, 0,
+			RK3568_CLKSEL_CON(73), 0, 2, MFLAGS,
+			RK3568_CLKGATE_CON(33), 0, GFLAGS),
+	COMPOSITE_NODIV(ACLK_TOP_LOW, "aclk_top_low", gpll400_gpll300_gpll200_xin24m_p, 0,
+			RK3568_CLKSEL_CON(73), 4, 2, MFLAGS,
+			RK3568_CLKGATE_CON(33), 1, GFLAGS),
+	COMPOSITE_NODIV(HCLK_TOP, "hclk_top", gpll150_gpll100_gpll75_xin24m_p, 0,
+			RK3568_CLKSEL_CON(73), 8, 2, MFLAGS,
+			RK3568_CLKGATE_CON(33), 2, GFLAGS),
+	COMPOSITE_NODIV(PCLK_TOP, "pclk_top", gpll100_gpll75_cpll50_xin24m_p, 0,
+			RK3568_CLKSEL_CON(73), 12, 2, MFLAGS,
+			RK3568_CLKGATE_CON(33), 3, GFLAGS),
+	GATE(PCLK_PCIE30PHY, "pclk_pcie30phy", "pclk_top", 0,
+			RK3568_CLKGATE_CON(33), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_OPTC_ARB, "clk_optc_arb", xin24m_cpll100_p, 0,
+			RK3568_CLKSEL_CON(73), 15, 1, MFLAGS,
+			RK3568_CLKGATE_CON(33), 9, GFLAGS),
+	GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top", 0,
+			RK3568_CLKGATE_CON(33), 13, GFLAGS),
+	GATE(PCLK_MIPIDSIPHY0, "pclk_mipidsiphy0", "pclk_top", 0,
+			RK3568_CLKGATE_CON(33), 14, GFLAGS),
+	GATE(PCLK_MIPIDSIPHY1, "pclk_mipidsiphy1", "pclk_top", 0,
+			RK3568_CLKGATE_CON(33), 15, GFLAGS),
+	GATE(PCLK_PIPEPHY0, "pclk_pipephy0", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 4, GFLAGS),
+	GATE(PCLK_PIPEPHY1, "pclk_pipephy1", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 5, GFLAGS),
+	GATE(PCLK_PIPEPHY2, "pclk_pipephy2", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 6, GFLAGS),
+	GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 11, GFLAGS),
+	GATE(CLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 0,
+			RK3568_CLKGATE_CON(34), 12, GFLAGS),
+	GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 13, GFLAGS),
+	GATE(PCLK_EDPPHY_GRF, "pclk_edpphy_grf", "pclk_top", 0,
+			RK3568_CLKGATE_CON(34), 14, GFLAGS),
+};
+
+static struct rockchip_clk_branch rk3568_clk_pmu_branches[] __initdata = {
+	/* PD_PMU */
+	FACTOR(0, "ppll_ph0", "ppll", 0, 1, 2),
+	FACTOR(0, "ppll_ph180", "ppll", 0, 1, 2),
+	FACTOR(0, "hpll_ph0", "hpll", 0, 1, 2),
+
+	MUX(CLK_PDPMU, "clk_pdpmu", clk_pdpmu_p, 0,
+			RK3568_PMU_CLKSEL_CON(2), 15, 1, MFLAGS),
+	COMPOSITE_NOMUX(PCLK_PDPMU, "pclk_pdpmu", "clk_pdpmu", 0,
+			RK3568_PMU_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(0), 6, GFLAGS),
+	GATE(CLK_PMU, "clk_pmu", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_I2C0, "clk_i2c0", "clk_pdpmu", 0,
+			RK3568_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(1), 2, GFLAGS),
+
+	COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED,
+			RK3568_PMU_CLKSEL_CON(1), 0,
+			RK3568_PMU_CLKGATE_CON(0), 1, GFLAGS,
+			&rk3568_rtc32k_pmu_fracmux),
+
+	COMPOSITE_NOMUX(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", CLK_IGNORE_UNUSED,
+			RK3568_PMU_CLKSEL_CON(0), 0, 5, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(0), 0, GFLAGS),
+
+	COMPOSITE(CLK_UART0_DIV, "sclk_uart0_div", ppll_usb480m_cpll_gpll_p, 0,
+			RK3568_PMU_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE_FRACMUX(CLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_div", CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(5), 0,
+			RK3568_PMU_CLKGATE_CON(1), 4, GFLAGS,
+			&rk3568_uart0_fracmux),
+	GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 0,
+			RK3568_PMU_CLKGATE_CON(1), 5, GFLAGS),
+
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", xin24m_32k_p, 0,
+			RK3568_PMU_CLKSEL_CON(6), 15, 1, MFLAGS,
+			RK3568_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE(CLK_PWM0, "clk_pwm0", clk_pwm0_p, 0,
+			RK3568_PMU_CLKSEL_CON(6), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	GATE(CLK_CAPTURE_PWM0_NDFT, "clk_capture_pwm0_ndft", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 0,
+			RK3568_PMU_CLKGATE_CON(1), 11, GFLAGS),
+	GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE_NOMUX(CLK_REF24M, "clk_ref24m", "clk_pdpmu", 0,
+			RK3568_PMU_CLKSEL_CON(7), 0, 6, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	GATE(XIN_OSC0_USBPHY0_G, "xin_osc0_usbphy0_g", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 1, GFLAGS),
+	MUX(CLK_USBPHY0_REF, "clk_usbphy0_ref", clk_usbphy0_ref_p, 0,
+			RK3568_PMU_CLKSEL_CON(8), 0, 1, MFLAGS),
+	GATE(XIN_OSC0_USBPHY1_G, "xin_osc0_usbphy1_g", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 2, GFLAGS),
+	MUX(CLK_USBPHY1_REF, "clk_usbphy1_ref", clk_usbphy1_ref_p, 0,
+			RK3568_PMU_CLKSEL_CON(8), 1, 1, MFLAGS),
+	GATE(XIN_OSC0_MIPIDSIPHY0_G, "xin_osc0_mipidsiphy0_g", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 3, GFLAGS),
+	MUX(CLK_MIPIDSIPHY0_REF, "clk_mipidsiphy0_ref", clk_mipidsiphy0_ref_p, 0,
+			RK3568_PMU_CLKSEL_CON(8), 2, 1, MFLAGS),
+	GATE(XIN_OSC0_MIPIDSIPHY1_G, "xin_osc0_mipidsiphy1_g", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 4, GFLAGS),
+	MUX(CLK_MIPIDSIPHY1_REF, "clk_mipidsiphy1_ref", clk_mipidsiphy1_ref_p, 0,
+			RK3568_PMU_CLKSEL_CON(8), 3, 1, MFLAGS),
+	COMPOSITE_NOMUX(CLK_WIFI_DIV, "clk_wifi_div", "clk_pdpmu", 0,
+			RK3568_PMU_CLKSEL_CON(8), 8, 6, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(2), 5, GFLAGS),
+	GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 6, GFLAGS),
+	MUX(CLK_WIFI, "clk_wifi", clk_wifi_p, CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(8), 15, 1, MFLAGS),
+	COMPOSITE_NOMUX(CLK_PCIEPHY0_DIV, "clk_pciephy0_div", "ppll_ph0", 0,
+			RK3568_PMU_CLKSEL_CON(9), 0, 3, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(2), 7, GFLAGS),
+	GATE(CLK_PCIEPHY0_OSC0, "clk_pciephy0_osc0", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 8, GFLAGS),
+	MUX(CLK_PCIEPHY0_REF, "clk_pciephy0_ref", clk_pciephy0_ref_p, CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(9), 3, 1, MFLAGS),
+	COMPOSITE_NOMUX(CLK_PCIEPHY1_DIV, "clk_pciephy1_div", "ppll_ph0", 0,
+			RK3568_PMU_CLKSEL_CON(9), 4, 3, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(2), 9, GFLAGS),
+	GATE(CLK_PCIEPHY1_OSC0, "clk_pciephy1_osc0", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 10, GFLAGS),
+	MUX(CLK_PCIEPHY1_REF, "clk_pciephy1_ref", clk_pciephy1_ref_p, CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(9), 7, 1, MFLAGS),
+	COMPOSITE_NOMUX(CLK_PCIEPHY2_DIV, "clk_pciephy2_div", "ppll_ph0", 0,
+			RK3568_PMU_CLKSEL_CON(9), 8, 3, DFLAGS,
+			RK3568_PMU_CLKGATE_CON(2), 11, GFLAGS),
+	GATE(CLK_PCIEPHY2_OSC0, "clk_pciephy2_osc0", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 12, GFLAGS),
+	MUX(CLK_PCIEPHY2_REF, "clk_pciephy2_ref", clk_pciephy2_ref_p, CLK_SET_RATE_PARENT,
+			RK3568_PMU_CLKSEL_CON(9), 11, 1, MFLAGS),
+	GATE(CLK_PCIE30PHY_REF_M, "clk_pcie30phy_ref_m", "ppll_ph0", 0,
+			RK3568_PMU_CLKGATE_CON(2), 13, GFLAGS),
+	GATE(CLK_PCIE30PHY_REF_N, "clk_pcie30phy_ref_n", "ppll_ph180", 0,
+			RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS),
+	GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0,
+			RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS),
+	MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0,
+			RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS),
+};
+
+static const char *const rk3568_cru_critical_clocks[] __initconst = {
+	"armclk",
+	"pclk_core_pre",
+	"aclk_bus",
+	"pclk_bus",
+	"aclk_top_high",
+	"aclk_top_low",
+	"hclk_top",
+	"pclk_top",
+	"aclk_perimid",
+	"hclk_perimid",
+	"aclk_secure_flash",
+	"hclk_secure_flash",
+	"aclk_core_niu2bus",
+	"npll",
+	"clk_optc_arb",
+	"hclk_php",
+	"pclk_php",
+	"hclk_usb",
+};
+
+static const char *const rk3568_pmucru_critical_clocks[] __initconst = {
+	"pclk_pdpmu",
+	"pclk_pmu",
+	"clk_pmu",
+};
+
+static void __init rk3568_pmu_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru pmu region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip pmu clk init failed\n", __func__);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3568_pmu_pll_clks,
+				   ARRAY_SIZE(rk3568_pmu_pll_clks),
+				   RK3568_GRF_SOC_STATUS0);
+
+	rockchip_clk_register_branches(ctx, rk3568_clk_pmu_branches,
+				       ARRAY_SIZE(rk3568_clk_pmu_branches));
+
+	rockchip_clk_protect_critical(rk3568_pmucru_critical_clocks,
+				      ARRAY_SIZE(rk3568_pmucru_critical_clocks));
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+
+static void __init rk3568_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3568_pll_clks,
+				   ARRAY_SIZE(rk3568_pll_clks),
+				   RK3568_GRF_SOC_STATUS0);
+
+	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
+				     mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+				     &rk3568_cpuclk_data, rk3568_cpuclk_rates,
+				     ARRAY_SIZE(rk3568_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3568_clk_branches,
+				       ARRAY_SIZE(rk3568_clk_branches));
+
+	rockchip_clk_protect_critical(rk3568_cru_critical_clocks,
+				      ARRAY_SIZE(rk3568_cru_critical_clocks));
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+
+struct clk_rk3568_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3568_inits clk_rk3568_pmucru_init = {
+	.inits = rk3568_pmu_clk_init,
+};
+
+static const struct clk_rk3568_inits clk_3568_cru_init = {
+	.inits = rk3568_clk_init,
+};
+
+static const struct of_device_id clk_rk3568_match_table[] = {
+	{
+		.compatible = "rockchip,rk3568-cru",
+		.data = &clk_3568_cru_init,
+	},  {
+		.compatible = "rockchip,rk3568-pmucru",
+		.data = &clk_rk3568_pmucru_init,
+	},
+	{ }
+};
+
+static int __init clk_rk3568_probe(struct device_d *dev)
+{
+	struct device_node *np = dev->device_node;
+	const struct clk_rk3568_inits *init_data;
+
+	init_data = of_device_get_match_data(dev);
+	if (init_data->inits)
+		init_data->inits(np);
+
+	return 0;
+}
+
+static struct driver_d clk_rk3568_driver = {
+	.probe  = clk_rk3568_probe,
+	.name   = "clk-rk3568",
+	.of_compatible = DRV_OF_COMPAT(clk_rk3568_match_table),
+};
+
+core_platform_driver(clk_rk3568_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK
  2021-06-02  9:54 ` [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK Sascha Hauer
@ 2021-06-02 15:18   ` Ahmad Fatoum
  0 siblings, 0 replies; 34+ messages in thread
From: Ahmad Fatoum @ 2021-06-02 15:18 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List



On 02.06.21 11:54, Sascha Hauer wrote:
> CLK_MUX_HIWORD_MASK is a flag of the mux clock, not a generic clock
> flag.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  drivers/clk/clk-mux.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
> index a4743c51b0..7977a76db9 100644
> --- a/drivers/clk/clk-mux.c
> +++ b/drivers/clk/clk-mux.c
> @@ -34,7 +34,7 @@ static int clk_mux_set_parent(struct clk *clk, u8 idx)
>  	val &= ~(((1 << m->width) - 1) << m->shift);
>  	val |= idx << m->shift;
>  
> -	if (clk->flags & CLK_MUX_HIWORD_MASK)
> +	if (m->flags & CLK_MUX_HIWORD_MASK)
>  		val |= ((1 << m->width) - 1) << (m->shift + 16);
>  	writel(val, m->reg);
>  
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 11/24] Add rational_best_approximation()
  2021-06-02  9:54 ` [PATCH 11/24] Add rational_best_approximation() Sascha Hauer
@ 2021-06-02 18:25   ` Trent Piepho
  2021-06-07 11:22     ` Sascha Hauer
  0 siblings, 1 reply; 34+ messages in thread
From: Trent Piepho @ 2021-06-02 18:25 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List, Ahmad Fatoum

On Wed, Jun 2, 2021 at 3:05 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> Import rational_best_approximation() from Linux. This is used by an
> upcoming update of the clk_fractional_divider code.

> +               if ((n2 > max_numerator) || (d2 > max_denominator)) {
> +                       unsigned long t = min((max_numerator - n0) / n1,
> +                                             (max_denominator - d0) / d1);
> +

There is a divide by zero bug in this version if the input is greater
than the largest value allowed or less than the smallest non-zero
value allowed.  I sent a patch to lkml for this a week ago,
https://lore.kernel.org/patchwork/patch/1436255/

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 11/24] Add rational_best_approximation()
  2021-06-02 18:25   ` Trent Piepho
@ 2021-06-07 11:22     ` Sascha Hauer
  0 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-06-07 11:22 UTC (permalink / raw)
  To: Trent Piepho; +Cc: Barebox List, Ahmad Fatoum

On Wed, Jun 02, 2021 at 11:25:29AM -0700, Trent Piepho wrote:
> On Wed, Jun 2, 2021 at 3:05 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
> >
> > Import rational_best_approximation() from Linux. This is used by an
> > upcoming update of the clk_fractional_divider code.
> 
> > +               if ((n2 > max_numerator) || (d2 > max_denominator)) {
> > +                       unsigned long t = min((max_numerator - n0) / n1,
> > +                                             (max_denominator - d0) / d1);
> > +
> 
> There is a divide by zero bug in this version if the input is greater
> than the largest value allowed or less than the smallest non-zero
> value allowed.  I sent a patch to lkml for this a week ago,
> https://lore.kernel.org/patchwork/patch/1436255/

I applies that on top of the series.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 24/24] clk: Rockchip: Add rk3568 clk support
  2021-06-02  9:55 ` [PATCH 24/24] clk: Rockchip: Add rk3568 clk support Sascha Hauer
@ 2021-06-09  9:18   ` Ahmad Fatoum
  0 siblings, 0 replies; 34+ messages in thread
From: Ahmad Fatoum @ 2021-06-09  9:18 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List



On 02.06.21 11:55, Sascha Hauer wrote:
> This adds clock support for the Rockchip rk3568 SoC. Based on the
> corresponding Linux patch merged into v5.13-rc1.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/clk/rockchip/Makefile     |    1 +
>  drivers/clk/rockchip/clk-rk3568.c | 1704 +++++++++++++++++++++++++++++
>  2 files changed, 1705 insertions(+)
>  create mode 100644 drivers/clk/rockchip/clk-rk3568.c
> 
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index 9964b331f2..4c387b3a89 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -2,3 +2,4 @@
>  obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
>  obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
>  obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
> +obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
> diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
> new file mode 100644
> index 0000000000..d151437c12
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-rk3568.c
> @@ -0,0 +1,1704 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
> + * Author: Elaine Zhang <zhangqing@rock-chips.com>
> + */
> +
> +#include <common.h>
> +#include <linux/clk.h>
> +#include <of.h>
> +#include <of_address.h>
> +#include <linux/barebox-wrapper.h>
> +#include <init.h>
> +#include <linux/spinlock.h>
> +#include <of_device.h>
> +#include <dt-bindings/clock/rk3568-cru.h>
> +#include "clk.h"
> +
> +#define RK3568_GRF_SOC_STATUS0	0x580
> +
> +enum rk3568_pmu_plls {
> +	ppll, hpll,
> +};
> +
> +enum rk3568_plls {
> +	apll, dpll, gpll, cpll, npll, vpll,
> +};
> +
> +static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
> +	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
> +	RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
> +	RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
> +	RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0),
> +	RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0),
> +	RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
> +	RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
> +	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
> +	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
> +	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
> +	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
> +	RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
> +	RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
> +	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
> +	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
> +	RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
> +	{ /* sentinel */ },
> +};
> +
> +#define RK3568_DIV_ATCLK_CORE_MASK	0x1f
> +#define RK3568_DIV_ATCLK_CORE_SHIFT	0
> +#define RK3568_DIV_GICCLK_CORE_MASK	0x1f
> +#define RK3568_DIV_GICCLK_CORE_SHIFT	8
> +#define RK3568_DIV_PCLK_CORE_MASK	0x1f
> +#define RK3568_DIV_PCLK_CORE_SHIFT	0
> +#define RK3568_DIV_PERIPHCLK_CORE_MASK	0x1f
> +#define RK3568_DIV_PERIPHCLK_CORE_SHIFT	8
> +#define RK3568_DIV_ACLK_CORE_MASK	0x1f
> +#define RK3568_DIV_ACLK_CORE_SHIFT	8
> +
> +#define RK3568_DIV_SCLK_CORE_MASK	0xf
> +#define RK3568_DIV_SCLK_CORE_SHIFT	0
> +#define RK3568_MUX_SCLK_CORE_MASK	0x3
> +#define RK3568_MUX_SCLK_CORE_SHIFT	8
> +#define RK3568_MUX_SCLK_CORE_NPLL_MASK	0x1
> +#define RK3568_MUX_SCLK_CORE_NPLL_SHIFT	15
> +#define RK3568_MUX_CLK_CORE_APLL_MASK	0x1
> +#define RK3568_MUX_CLK_CORE_APLL_SHIFT	7
> +#define RK3568_MUX_CLK_PVTPLL_MASK	0x1
> +#define RK3568_MUX_CLK_PVTPLL_SHIFT	15
> +
> +#define RK3568_CLKSEL1(_sclk_core)					\
> +{								\
> +	.reg = RK3568_CLKSEL_CON(2),				\
> +	.val = HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_NPLL_MASK, \
> +			RK3568_MUX_SCLK_CORE_NPLL_SHIFT) |		\
> +	       HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_MASK, \
> +			RK3568_MUX_SCLK_CORE_SHIFT) |		\
> +		HIWORD_UPDATE(1, RK3568_DIV_SCLK_CORE_MASK, \
> +			RK3568_DIV_SCLK_CORE_SHIFT),		\
> +}
> +
> +#define RK3568_CLKSEL2(_aclk_core)					\
> +{								\
> +	.reg = RK3568_CLKSEL_CON(5),				\
> +	.val = HIWORD_UPDATE(_aclk_core, RK3568_DIV_ACLK_CORE_MASK, \
> +			RK3568_DIV_ACLK_CORE_SHIFT),		\
> +}
> +
> +#define RK3568_CLKSEL3(_atclk_core, _gic_core)	\
> +{								\
> +	.reg = RK3568_CLKSEL_CON(3),				\
> +	.val = HIWORD_UPDATE(_atclk_core, RK3568_DIV_ATCLK_CORE_MASK, \
> +			RK3568_DIV_ATCLK_CORE_SHIFT) |		\
> +	       HIWORD_UPDATE(_gic_core, RK3568_DIV_GICCLK_CORE_MASK, \
> +			RK3568_DIV_GICCLK_CORE_SHIFT),		\
> +}
> +
> +#define RK3568_CLKSEL4(_pclk_core, _periph_core)	\
> +{								\
> +	.reg = RK3568_CLKSEL_CON(4),				\
> +	.val = HIWORD_UPDATE(_pclk_core, RK3568_DIV_PCLK_CORE_MASK, \
> +			RK3568_DIV_PCLK_CORE_SHIFT) |		\
> +	       HIWORD_UPDATE(_periph_core, RK3568_DIV_PERIPHCLK_CORE_MASK, \
> +			RK3568_DIV_PERIPHCLK_CORE_SHIFT),		\
> +}
> +
> +#define RK3568_CPUCLK_RATE(_prate, _sclk, _acore, _atcore, _gicclk, _pclk, _periph) \
> +{								\
> +	.prate = _prate##U,					\
> +	.divs = {						\
> +		RK3568_CLKSEL1(_sclk),				\
> +		RK3568_CLKSEL2(_acore),				\
> +		RK3568_CLKSEL3(_atcore, _gicclk),		\
> +		RK3568_CLKSEL4(_pclk, _periph),			\
> +	},							\
> +}
> +
> +static struct rockchip_cpuclk_rate_table rk3568_cpuclk_rates[] __initdata = {
> +	RK3568_CPUCLK_RATE(1800000000, 0, 1, 7, 7, 7, 7),
> +	RK3568_CPUCLK_RATE(1704000000, 0, 1, 7, 7, 7, 7),
> +	RK3568_CPUCLK_RATE(1608000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1584000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1560000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1536000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1512000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1488000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1464000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1440000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1416000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1392000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1368000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1344000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1320000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1296000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1272000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1248000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1224000000, 0, 1, 5, 5, 5, 5),
> +	RK3568_CPUCLK_RATE(1200000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(1104000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(1008000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(912000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(816000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(696000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(600000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(408000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(312000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(216000000, 0, 1, 3, 3, 3, 3),
> +	RK3568_CPUCLK_RATE(96000000, 0, 1, 3, 3, 3, 3),
> +};
> +
> +static const struct rockchip_cpuclk_reg_data rk3568_cpuclk_data = {
> +	.core_reg[0] = RK3568_CLKSEL_CON(0),
> +	.div_core_shift[0] = 0,
> +	.div_core_mask[0] = 0x1f,
> +	.core_reg[1] = RK3568_CLKSEL_CON(0),
> +	.div_core_shift[1] = 8,
> +	.div_core_mask[1] = 0x1f,
> +	.core_reg[2] = RK3568_CLKSEL_CON(1),
> +	.div_core_shift[2] = 0,
> +	.div_core_mask[2] = 0x1f,
> +	.core_reg[3] = RK3568_CLKSEL_CON(1),
> +	.div_core_shift[3] = 8,
> +	.div_core_mask[3] = 0x1f,
> +	.num_cores = 4,
> +	.mux_core_alt = 1,
> +	.mux_core_main = 0,
> +	.mux_core_shift = 6,
> +	.mux_core_mask = 0x1,
> +};
> +
> +PNAME(mux_pll_p)			= { "xin24m" };
> +PNAME(mux_usb480m_p)			= { "xin24m", "usb480m_phy", "clk_rtc_32k" };
> +PNAME(mux_armclk_p)			= { "apll", "gpll" };
> +PNAME(clk_i2s0_8ch_tx_p)		= { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin_osc0_half" };
> +PNAME(clk_i2s0_8ch_rx_p)		= { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin_osc0_half" };
> +PNAME(clk_i2s1_8ch_tx_p)		= { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin_osc0_half" };
> +PNAME(clk_i2s1_8ch_rx_p)		= { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin_osc0_half" };
> +PNAME(clk_i2s2_2ch_p)			= { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin_osc0_half "};
> +PNAME(clk_i2s3_2ch_tx_p)		= { "clk_i2s3_2ch_tx_src", "clk_i2s3_2ch_tx_frac", "i2s3_mclkin", "xin_osc0_half" };
> +PNAME(clk_i2s3_2ch_rx_p)		= { "clk_i2s3_2ch_rx_src", "clk_i2s3_2ch_rx_frac", "i2s3_mclkin", "xin_osc0_half" };
> +PNAME(mclk_spdif_8ch_p)			= { "mclk_spdif_8ch_src", "mclk_spdif_8ch_frac" };
> +PNAME(sclk_audpwm_p)			= { "sclk_audpwm_src", "sclk_audpwm_frac" };
> +PNAME(sclk_uart1_p)			= { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
> +PNAME(sclk_uart2_p)			= { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
> +PNAME(sclk_uart3_p)			= { "clk_uart3_src", "clk_uart3_frac", "xin24m" };
> +PNAME(sclk_uart4_p)			= { "clk_uart4_src", "clk_uart4_frac", "xin24m" };
> +PNAME(sclk_uart5_p)			= { "clk_uart5_src", "clk_uart5_frac", "xin24m" };
> +PNAME(sclk_uart6_p)			= { "clk_uart6_src", "clk_uart6_frac", "xin24m" };
> +PNAME(sclk_uart7_p)			= { "clk_uart7_src", "clk_uart7_frac", "xin24m" };
> +PNAME(sclk_uart8_p)			= { "clk_uart8_src", "clk_uart8_frac", "xin24m" };
> +PNAME(sclk_uart9_p)			= { "clk_uart9_src", "clk_uart9_frac", "xin24m" };
> +PNAME(sclk_uart0_p)			= { "sclk_uart0_div", "sclk_uart0_frac", "xin24m" };
> +PNAME(clk_rtc32k_pmu_p)			= { "clk_32k_pvtm", "xin32k", "clk_rtc32k_frac" };
> +PNAME(mpll_gpll_cpll_npll_p)		= { "mpll", "gpll", "cpll", "npll" };
> +PNAME(gpll_cpll_npll_p)			= { "gpll", "cpll", "npll" };
> +PNAME(npll_gpll_p)			= { "npll", "gpll" };
> +PNAME(cpll_gpll_p)			= { "cpll", "gpll" };
> +PNAME(gpll_cpll_p)			= { "gpll", "cpll" };
> +PNAME(gpll_cpll_npll_vpll_p)		= { "gpll", "cpll", "npll", "vpll" };
> +PNAME(apll_gpll_npll_p)			= { "apll", "gpll", "npll" };
> +PNAME(sclk_core_pre_p)			= { "sclk_core_src", "npll" };
> +PNAME(gpll150_gpll100_gpll75_xin24m_p)	= { "gpll_150m", "gpll_100m", "gpll_75m", "xin24m" };
> +PNAME(clk_gpu_pre_mux_p)		= { "clk_gpu_src", "gpu_pvtpll_out" };
> +PNAME(clk_npu_pre_ndft_p)		= { "clk_npu_src", "dummy"};
> +PNAME(clk_npu_p)			= { "clk_npu_pre_ndft", "npu_pvtpll_out" };
> +PNAME(dpll_gpll_cpll_p)			= { "dpll", "gpll", "cpll" };
> +PNAME(clk_ddr1x_p)			= { "clk_ddrphy1x_src", "dpll" };
> +PNAME(gpll200_gpll150_gpll100_xin24m_p)	= { "gpll_200m", "gpll_150m", "gpll_100m", "xin24m" };
> +PNAME(gpll100_gpll75_gpll50_p)		= { "gpll_100m", "gpll_75m", "cpll_50m" };
> +PNAME(i2s0_mclkout_tx_p)		= { "clk_i2s0_8ch_tx", "xin_osc0_half" };
> +PNAME(i2s0_mclkout_rx_p)		= { "clk_i2s0_8ch_rx", "xin_osc0_half" };
> +PNAME(i2s1_mclkout_tx_p)		= { "clk_i2s1_8ch_tx", "xin_osc0_half" };
> +PNAME(i2s1_mclkout_rx_p)		= { "clk_i2s1_8ch_rx", "xin_osc0_half" };
> +PNAME(i2s2_mclkout_p)			= { "clk_i2s2_2ch", "xin_osc0_half" };
> +PNAME(i2s3_mclkout_tx_p)		= { "clk_i2s3_2ch_tx", "xin_osc0_half" };
> +PNAME(i2s3_mclkout_rx_p)		= { "clk_i2s3_2ch_rx", "xin_osc0_half" };
> +PNAME(mclk_pdm_p)			= { "gpll_300m", "cpll_250m", "gpll_200m", "gpll_100m" };
> +PNAME(clk_i2c_p)			= { "gpll_200m", "gpll_100m", "xin24m", "cpll_100m" };
> +PNAME(gpll200_gpll150_gpll100_p)	= { "gpll_200m", "gpll_150m", "gpll_100m" };
> +PNAME(gpll300_gpll200_gpll100_p)	= { "gpll_300m", "gpll_200m", "gpll_100m" };
> +PNAME(clk_nandc_p)			= { "gpll_200m", "gpll_150m", "cpll_100m", "xin24m" };
> +PNAME(sclk_sfc_p)			= { "xin24m", "cpll_50m", "gpll_75m", "gpll_100m", "cpll_125m", "gpll_150m" };
> +PNAME(gpll200_gpll150_cpll125_p)	= { "gpll_200m", "gpll_150m", "cpll_125m" };
> +PNAME(cclk_emmc_p)			= { "xin24m", "gpll_200m", "gpll_150m", "cpll_100m", "cpll_50m", "clk_osc0_div_375k" };
> +PNAME(aclk_pipe_p)			= { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
> +PNAME(gpll200_cpll125_p)		= { "gpll_200m", "cpll_125m" };
> +PNAME(gpll300_gpll200_gpll100_xin24m_p)	= { "gpll_300m", "gpll_200m", "gpll_100m", "xin24m" };
> +PNAME(clk_sdmmc_p)			= { "xin24m", "gpll_400m", "gpll_300m", "cpll_100m", "cpll_50m", "clk_osc0_div_750k" };
> +PNAME(cpll125_cpll50_cpll25_xin24m_p)	= { "cpll_125m", "cpll_50m", "cpll_25m", "xin24m" };
> +PNAME(clk_gmac_ptp_p)			= { "cpll_62p5", "gpll_100m", "cpll_50m", "xin24m" };
> +PNAME(cpll333_gpll300_gpll200_p)	= { "cpll_333m", "gpll_300m", "gpll_200m" };
> +PNAME(cpll_gpll_hpll_p)			= { "cpll", "gpll", "hpll" };
> +PNAME(gpll_usb480m_xin24m_p)		= { "gpll", "usb480m", "xin24m", "xin24m" };
> +PNAME(gpll300_cpll250_gpll100_xin24m_p)	= { "gpll_300m", "cpll_250m", "gpll_100m", "xin24m" };
> +PNAME(cpll_gpll_hpll_vpll_p)		= { "cpll", "gpll", "hpll", "vpll" };
> +PNAME(hpll_vpll_gpll_cpll_p)		= { "hpll", "vpll", "gpll", "cpll" };
> +PNAME(gpll400_cpll333_gpll200_p)	= { "gpll_400m", "cpll_333m", "gpll_200m" };
> +PNAME(gpll100_gpll75_cpll50_xin24m_p)	= { "gpll_100m", "gpll_75m", "cpll_50m", "xin24m" };
> +PNAME(xin24m_gpll100_cpll100_p)		= { "xin24m", "gpll_100m", "cpll_100m" };
> +PNAME(gpll_cpll_usb480m_p)		= { "gpll", "cpll", "usb480m" };
> +PNAME(gpll100_xin24m_cpll100_p)		= { "gpll_100m", "xin24m", "cpll_100m" };
> +PNAME(gpll200_xin24m_cpll100_p)		= { "gpll_200m", "xin24m", "cpll_100m" };
> +PNAME(xin24m_32k_p)			= { "xin24m", "clk_rtc_32k" };
> +PNAME(cpll500_gpll400_gpll300_xin24m_p)	= { "cpll_500m", "gpll_400m", "gpll_300m", "xin24m" };
> +PNAME(gpll400_gpll300_gpll200_xin24m_p)	= { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
> +PNAME(xin24m_cpll100_p)			= { "xin24m", "cpll_100m" };
> +PNAME(ppll_usb480m_cpll_gpll_p)		= { "ppll", "usb480m", "cpll", "gpll"};
> +PNAME(clk_usbphy0_ref_p)		= { "clk_ref24m", "xin_osc0_usbphy0_g" };
> +PNAME(clk_usbphy1_ref_p)		= { "clk_ref24m", "xin_osc0_usbphy1_g" };
> +PNAME(clk_mipidsiphy0_ref_p)		= { "clk_ref24m", "xin_osc0_mipidsiphy0_g" };
> +PNAME(clk_mipidsiphy1_ref_p)		= { "clk_ref24m", "xin_osc0_mipidsiphy1_g" };
> +PNAME(clk_wifi_p)			= { "clk_wifi_osc0", "clk_wifi_div" };
> +PNAME(clk_pciephy0_ref_p)		= { "clk_pciephy0_osc0", "clk_pciephy0_div" };
> +PNAME(clk_pciephy1_ref_p)		= { "clk_pciephy1_osc0", "clk_pciephy1_div" };
> +PNAME(clk_pciephy2_ref_p)		= { "clk_pciephy2_osc0", "clk_pciephy2_div" };
> +PNAME(mux_gmac0_p)			= { "clk_mac0_2top", "gmac0_clkin" };
> +PNAME(mux_gmac0_rgmii_speed_p)		= { "clk_gmac0", "clk_gmac0", "clk_gmac0_tx_div50", "clk_gmac0_tx_div5" };
> +PNAME(mux_gmac0_rmii_speed_p)		= { "clk_gmac0_rx_div20", "clk_gmac0_rx_div2" };
> +PNAME(mux_gmac0_rx_tx_p)		= { "clk_gmac0_rgmii_speed", "clk_gmac0_rmii_speed", "clk_gmac0_xpcs_mii" };
> +PNAME(mux_gmac1_p)			= { "clk_mac1_2top", "gmac1_clkin" };
> +PNAME(mux_gmac1_rgmii_speed_p)		= { "clk_gmac1", "clk_gmac1", "clk_gmac1_tx_div50", "clk_gmac1_tx_div5" };
> +PNAME(mux_gmac1_rmii_speed_p)		= { "clk_gmac1_rx_div20", "clk_gmac1_rx_div2" };
> +PNAME(mux_gmac1_rx_tx_p)		= { "clk_gmac1_rgmii_speed", "clk_gmac1_rmii_speed", "clk_gmac1_xpcs_mii" };
> +PNAME(clk_hdmi_ref_p)			= { "hpll", "hpll_ph0" };
> +PNAME(clk_pdpmu_p)			= { "ppll", "gpll" };
> +PNAME(clk_mac_2top_p)			= { "cpll_125m", "cpll_50m", "cpll_25m", "ppll" };
> +PNAME(clk_pwm0_p)			= { "xin24m", "clk_pdpmu" };
> +PNAME(aclk_rkvdec_pre_p)		= { "gpll", "cpll" };
> +PNAME(clk_rkvdec_core_p)		= { "gpll", "cpll", "dummy_npll", "dummy_vpll" };
> +
> +static struct rockchip_pll_clock rk3568_pmu_pll_clks[] __initdata = {
> +	[ppll] = PLL(pll_rk3328, PLL_PPLL, "ppll",  mux_pll_p,
> +		     0, RK3568_PMU_PLL_CON(0),
> +		     RK3568_PMU_MODE_CON0, 0, 4, 0, rk3568_pll_rates),
> +	[hpll] = PLL(pll_rk3328, PLL_HPLL, "hpll",  mux_pll_p,
> +		     0, RK3568_PMU_PLL_CON(16),
> +		     RK3568_PMU_MODE_CON0, 2, 7, 0, rk3568_pll_rates),
> +};
> +
> +static struct rockchip_pll_clock rk3568_pll_clks[] __initdata = {
> +	[apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
> +		     0, RK3568_PLL_CON(0),
> +		     RK3568_MODE_CON0, 0, 0, 0, rk3568_pll_rates),
> +	[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
> +		     0, RK3568_PLL_CON(8),
> +		     RK3568_MODE_CON0, 2, 1, 0, NULL),
> +	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
> +		     0, RK3568_PLL_CON(24),
> +		     RK3568_MODE_CON0, 4, 2, 0, rk3568_pll_rates),
> +	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
> +		     0, RK3568_PLL_CON(16),
> +		     RK3568_MODE_CON0, 6, 3, 0, rk3568_pll_rates),
> +	[npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p,
> +		     0, RK3568_PLL_CON(32),
> +		     RK3568_MODE_CON0, 10, 5, 0, rk3568_pll_rates),
> +	[vpll] = PLL(pll_rk3328, PLL_VPLL, "vpll", mux_pll_p,
> +		     0, RK3568_PLL_CON(40),
> +		     RK3568_MODE_CON0, 12, 6, 0, rk3568_pll_rates),
> +};
> +
> +#define MFLAGS CLK_MUX_HIWORD_MASK
> +#define DFLAGS CLK_DIVIDER_HIWORD_MASK
> +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
> +
> +static struct rockchip_clk_branch rk3568_i2s0_8ch_tx_fracmux __initdata =
> +	MUX(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(11), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s0_8ch_rx_fracmux __initdata =
> +	MUX(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(13), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s1_8ch_tx_fracmux __initdata =
> +	MUX(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(15), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s1_8ch_rx_fracmux __initdata =
> +	MUX(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(17), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s2_2ch_fracmux __initdata =
> +	MUX(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(19), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s3_2ch_tx_fracmux __initdata =
> +	MUX(CLK_I2S3_2CH_TX, "clk_i2s3_2ch_tx", clk_i2s3_2ch_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(21), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_i2s3_2ch_rx_fracmux __initdata =
> +	MUX(CLK_I2S3_2CH_RX, "clk_i2s3_2ch_rx", clk_i2s3_2ch_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(83), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_spdif_8ch_fracmux __initdata =
> +	MUX(MCLK_SPDIF_8CH, "mclk_spdif_8ch", mclk_spdif_8ch_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(23), 15, 1, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_audpwm_fracmux __initdata =
> +	MUX(SCLK_AUDPWM, "sclk_audpwm", sclk_audpwm_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(25), 15, 1, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart1_fracmux __initdata =
> +	MUX(0, "sclk_uart1_mux", sclk_uart1_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(52), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart2_fracmux __initdata =
> +	MUX(0, "sclk_uart2_mux", sclk_uart2_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(54), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart3_fracmux __initdata =
> +	MUX(0, "sclk_uart3_mux", sclk_uart3_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(56), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart4_fracmux __initdata =
> +	MUX(0, "sclk_uart4_mux", sclk_uart4_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(58), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart5_fracmux __initdata =
> +	MUX(0, "sclk_uart5_mux", sclk_uart5_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(60), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart6_fracmux __initdata =
> +	MUX(0, "sclk_uart6_mux", sclk_uart6_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(62), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart7_fracmux __initdata =
> +	MUX(0, "sclk_uart7_mux", sclk_uart7_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(64), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart8_fracmux __initdata =
> +	MUX(0, "sclk_uart8_mux", sclk_uart8_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(66), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart9_fracmux __initdata =
> +	MUX(0, "sclk_uart9_mux", sclk_uart9_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(68), 12, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_uart0_fracmux __initdata =
> +	MUX(0, "sclk_uart0_mux", sclk_uart0_p, CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(4), 10, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_rtc32k_pmu_fracmux __initdata =
> +	MUX(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +			RK3568_PMU_CLKSEL_CON(0), 6, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
> +	/*
> +	 * Clock-Architecture Diagram 1
> +	 */
> +	 /* SRC_CLK */
> +	COMPOSITE_NOMUX(0, "gpll_400m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(75), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 0, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_300m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(75), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 1, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_200m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(76), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 2, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_150m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(76), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 3, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_100m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(77), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 4, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_75m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(77), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 5, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gpll_20m", "gpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(78), 0, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 6, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_500M, "cpll_500m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(78), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 7, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_333M, "cpll_333m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(79), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 8, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_250M, "cpll_250m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(79), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 9, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(80), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 10, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(80), 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 11, GFLAGS),

There's a fix for this on linux-clk[1]. This should read

RK3568_CLKGATE_CON(35), 12, GFLAGS)

along with some other hunks.

https://lore.kernel.org/linux-clk/91fb0c11-1626-4a8c-7e01-2ef71faddc64@rock-chips.com/

> +	COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(81), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 12, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(81), 8, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 13, GFLAGS),
> +	COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 14, GFLAGS),
> +	COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(82), 8, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(35), 15, GFLAGS),
> +	FACTOR(0, "clk_osc0_div_375k", "clk_osc0_div_750k", 0, 1, 2),
> +	FACTOR(0, "xin_osc0_half", "xin24m", 0, 1, 2),
> +	MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
> +			RK3568_MODE_CON0, 14, 2, MFLAGS),
> +
> +	/* PD_CORE */
> +	COMPOSITE(0, "sclk_core_src", apll_gpll_npll_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 5, GFLAGS),
> +	COMPOSITE_NODIV(0, "sclk_core", sclk_core_pre_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(2), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(0), 7, GFLAGS),
> +
> +	COMPOSITE_NOMUX(0, "atclk_core", "armclk", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 8, GFLAGS),
> +	COMPOSITE_NOMUX(0, "gicclk_core", "armclk", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 9, GFLAGS),
> +	COMPOSITE_NOMUX(0, "pclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(4), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 10, GFLAGS),
> +	COMPOSITE_NOMUX(0, "periphclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(4), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 11, GFLAGS),
> +	COMPOSITE_NOMUX(0, "tsclk_core", "periphclk_core_pre", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(5), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 14, GFLAGS),
> +	COMPOSITE_NOMUX(0, "cntclk_core", "periphclk_core_pre", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(5), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(0), 15, GFLAGS),
> +	COMPOSITE_NOMUX(0, "aclk_core", "sclk_core", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(5), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(1), 0, GFLAGS),
> +
> +	COMPOSITE_NODIV(ACLK_CORE_NIU2BUS, "aclk_core_niu2bus", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(5), 14, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(1), 2, GFLAGS),
> +
> +	GATE(CLK_CORE_PVTM, "clk_core_pvtm", "xin24m", 0,
> +			RK3568_CLKGATE_CON(1), 10, GFLAGS),
> +	GATE(CLK_CORE_PVTM_CORE, "clk_core_pvtm_core", "armclk", 0,
> +			RK3568_CLKGATE_CON(1), 11, GFLAGS),
> +	GATE(CLK_CORE_PVTPLL, "clk_core_pvtpll", "armclk", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(1), 12, GFLAGS),
> +	GATE(PCLK_CORE_PVTM, "pclk_core_pvtm", "pclk_core_pre", 0,
> +			RK3568_CLKGATE_CON(1), 9, GFLAGS),
> +
> +	/* PD_GPU */
> +	COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", mpll_gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(6), 6, 2, MFLAGS | CLK_MUX_READ_ONLY, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK3568_CLKGATE_CON(2), 0, GFLAGS),
> +	MUX(CLK_GPU_PRE_MUX, "clk_gpu_pre_mux", clk_gpu_pre_mux_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(6), 11, 1, MFLAGS | CLK_MUX_READ_ONLY),
> +	DIV(ACLK_GPU_PRE, "aclk_gpu_pre", "clk_gpu_pre_mux", 0,
> +			RK3568_CLKSEL_CON(6), 8, 2, DFLAGS),
> +	DIV(PCLK_GPU_PRE, "pclk_gpu_pre", "clk_gpu_pre_mux", 0,
> +			RK3568_CLKSEL_CON(6), 12, 4, DFLAGS),
> +	GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre_mux", 0,
> +			RK3568_CLKGATE_CON(2), 3, GFLAGS),
> +
> +	GATE(PCLK_GPU_PVTM, "pclk_gpu_pvtm", "pclk_gpu_pre", 0,
> +			RK3568_CLKGATE_CON(2), 6, GFLAGS),
> +	GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0,
> +			RK3568_CLKGATE_CON(2), 7, GFLAGS),
> +	GATE(CLK_GPU_PVTM_CORE, "clk_gpu_pvtm_core", "clk_gpu_src", 0,
> +			RK3568_CLKGATE_CON(2), 8, GFLAGS),
> +	GATE(CLK_GPU_PVTPLL, "clk_gpu_pvtpll", "clk_gpu_src", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(2), 9, GFLAGS),
> +
> +	/* PD_NPU */
> +	COMPOSITE(CLK_NPU_SRC, "clk_npu_src", npll_gpll_p, 0,
> +			RK3568_CLKSEL_CON(7), 6, 1, MFLAGS, 0, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(3), 0, GFLAGS),
> +	MUX(CLK_NPU_PRE_NDFT, "clk_npu_pre_ndft", clk_npu_pre_ndft_p, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
> +			RK3568_CLKSEL_CON(7), 8, 1, MFLAGS),
> +	MUX(CLK_NPU, "clk_npu", clk_npu_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(7), 15, 1, MFLAGS),
> +	COMPOSITE_NOMUX(HCLK_NPU_PRE, "hclk_npu_pre", "clk_npu", 0,
> +			RK3568_CLKSEL_CON(8), 0, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(3), 2, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_NPU_PRE, "pclk_npu_pre", "clk_npu", 0,
> +			RK3568_CLKSEL_CON(8), 4, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(3), 3, GFLAGS),
> +	GATE(ACLK_NPU_PRE, "aclk_npu_pre", "clk_npu", 0,
> +			RK3568_CLKGATE_CON(3), 4, GFLAGS),
> +	GATE(ACLK_NPU, "aclk_npu", "aclk_npu_pre", 0,
> +			RK3568_CLKGATE_CON(3), 7, GFLAGS),
> +	GATE(HCLK_NPU, "hclk_npu", "hclk_npu_pre", 0,
> +			RK3568_CLKGATE_CON(3), 8, GFLAGS),
> +
> +	GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_pre", 0,
> +			RK3568_CLKGATE_CON(3), 9, GFLAGS),
> +	GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0,
> +			RK3568_CLKGATE_CON(3), 10, GFLAGS),
> +	GATE(CLK_NPU_PVTM_CORE, "clk_npu_pvtm_core", "clk_npu_pre_ndft", 0,
> +			RK3568_CLKGATE_CON(3), 11, GFLAGS),
> +	GATE(CLK_NPU_PVTPLL, "clk_npu_pvtpll", "clk_npu_pre_ndft", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(3), 12, GFLAGS),
> +
> +	/* PD_DDR */
> +	COMPOSITE(CLK_DDRPHY1X_SRC, "clk_ddrphy1x_src", dpll_gpll_cpll_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(4), 0, GFLAGS),
> +	MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(9), 15, 1, MFLAGS),
> +
> +	COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
> +			RK3568_CLKGATE_CON(4), 2, GFLAGS),
> +	GATE(CLK24_DDRMON, "clk24_ddrmon", "xin24m", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(4), 15, GFLAGS),
> +
> +	/* PD_GIC_AUDIO */
> +	COMPOSITE_NODIV(ACLK_GIC_AUDIO, "aclk_gic_audio", gpll200_gpll150_gpll100_xin24m_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(10), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(5), 0, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_GIC_AUDIO, "hclk_gic_audio", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(10), 10, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(5), 1, GFLAGS),
> +	GATE(HCLK_SDMMC_BUFFER, "hclk_sdmmc_buffer", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 8, GFLAGS),
> +	COMPOSITE_NODIV(DCLK_SDMMC_BUFFER, "dclk_sdmmc_buffer", gpll100_gpll75_gpll50_p, 0,
> +			RK3568_CLKSEL_CON(10), 12, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(5), 9, GFLAGS),
> +	GATE(ACLK_GIC600, "aclk_gic600", "aclk_gic_audio", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(5), 4, GFLAGS),
> +	GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_gic_audio", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(5), 7, GFLAGS),
> +	GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 10, GFLAGS),
> +	GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 11, GFLAGS),
> +	GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 12, GFLAGS),
> +	GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 13, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(6), 0, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(12), 0,
> +			RK3568_CLKGATE_CON(6), 1, GFLAGS,
> +			&rk3568_i2s0_8ch_tx_fracmux),
> +	GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0,
> +			RK3568_CLKGATE_CON(6), 2, GFLAGS),
> +	COMPOSITE_NODIV(I2S0_MCLKOUT_TX, "i2s0_mclkout_tx", i2s0_mclkout_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(11), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(6), 3, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(13), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(6), 4, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(14), 0,
> +			RK3568_CLKGATE_CON(6), 5, GFLAGS,
> +			&rk3568_i2s0_8ch_rx_fracmux),
> +	GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0,
> +			RK3568_CLKGATE_CON(6), 6, GFLAGS),
> +	COMPOSITE_NODIV(I2S0_MCLKOUT_RX, "i2s0_mclkout_rx", i2s0_mclkout_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(13), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(6), 7, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(15), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(6), 8, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(16), 0,
> +			RK3568_CLKGATE_CON(6), 9, GFLAGS,
> +			&rk3568_i2s1_8ch_tx_fracmux),
> +	GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0,
> +			RK3568_CLKGATE_CON(6), 10, GFLAGS),
> +	COMPOSITE_NODIV(I2S1_MCLKOUT_TX, "i2s1_mclkout_tx", i2s1_mclkout_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(15), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(6), 11, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(6), 12, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(18), 0,
> +			RK3568_CLKGATE_CON(6), 13, GFLAGS,
> +			&rk3568_i2s1_8ch_rx_fracmux),
> +	GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0,
> +			RK3568_CLKGATE_CON(6), 14, GFLAGS),
> +	COMPOSITE_NODIV(I2S1_MCLKOUT_RX, "i2s1_mclkout_rx", i2s1_mclkout_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(17), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(6), 15, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(7), 0, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(20), 0,
> +			RK3568_CLKGATE_CON(7), 1, GFLAGS,
> +			&rk3568_i2s2_2ch_fracmux),
> +	GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0,
> +			RK3568_CLKGATE_CON(7), 2, GFLAGS),
> +	COMPOSITE_NODIV(I2S2_MCLKOUT, "i2s2_mclkout", i2s2_mclkout_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(19), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(7), 3, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S3_2CH_TX_SRC, "clk_i2s3_2ch_tx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(7), 4, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S3_2CH_TX_FRAC, "clk_i2s3_2ch_tx_frac", "clk_i2s3_2ch_tx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(22), 0,
> +			RK3568_CLKGATE_CON(7), 5, GFLAGS,
> +			&rk3568_i2s3_2ch_tx_fracmux),
> +	GATE(MCLK_I2S3_2CH_TX, "mclk_i2s3_2ch_tx", "clk_i2s3_2ch_tx", 0,
> +			RK3568_CLKGATE_CON(7), 6, GFLAGS),
> +	COMPOSITE_NODIV(I2S3_MCLKOUT_TX, "i2s3_mclkout_tx", i2s3_mclkout_tx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(21), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(7), 7, GFLAGS),
> +
> +	COMPOSITE(CLK_I2S3_2CH_RX_SRC, "clk_i2s3_2ch_rx_src", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(83), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(7), 8, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_I2S3_2CH_RX_FRAC, "clk_i2s3_2ch_rx_frac", "clk_i2s3_2ch_rx_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(84), 0,
> +			RK3568_CLKGATE_CON(7), 9, GFLAGS,
> +			&rk3568_i2s3_2ch_rx_fracmux),
> +	GATE(MCLK_I2S3_2CH_RX, "mclk_i2s3_2ch_rx", "clk_i2s3_2ch_rx", 0,
> +			RK3568_CLKGATE_CON(7), 10, GFLAGS),
> +	COMPOSITE_NODIV(I2S3_MCLKOUT_RX, "i2s3_mclkout_rx", i2s3_mclkout_rx_p, CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(83), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(7), 11, GFLAGS),
> +
> +	GATE(HCLK_PDM, "hclk_pdm", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(5), 14, GFLAGS),
> +	COMPOSITE_NODIV(MCLK_PDM, "mclk_pdm", mclk_pdm_p, 0,
> +			RK3568_CLKSEL_CON(23), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(5), 15, GFLAGS),
> +	GATE(HCLK_VAD, "hclk_vad", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(7), 12, GFLAGS),
> +	GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(7), 13, GFLAGS),
> +
> +	COMPOSITE(MCLK_SPDIF_8CH_SRC, "mclk_spdif_8ch_src", cpll_gpll_p, 0,
> +			RK3568_CLKSEL_CON(23), 14, 1, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(7), 14, GFLAGS),
> +	COMPOSITE_FRACMUX(MCLK_SPDIF_8CH_FRAC, "mclk_spdif_8ch_frac", "mclk_spdif_8ch_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(24), 0,
> +			RK3568_CLKGATE_CON(7), 15, GFLAGS,
> +			&rk3568_spdif_8ch_fracmux),
> +
> +	GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(8), 0, GFLAGS),
> +	COMPOSITE(SCLK_AUDPWM_SRC, "sclk_audpwm_src", gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(25), 14, 1, MFLAGS, 0, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(8), 1, GFLAGS),
> +	COMPOSITE_FRACMUX(SCLK_AUDPWM_FRAC, "sclk_audpwm_frac", "sclk_audpwm_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(26), 0,
> +			RK3568_CLKGATE_CON(8), 2, GFLAGS,
> +			&rk3568_audpwm_fracmux),
> +
> +	GATE(HCLK_ACDCDIG, "hclk_acdcdig", "hclk_gic_audio", 0,
> +			RK3568_CLKGATE_CON(8), 3, GFLAGS),
> +	COMPOSITE_NODIV(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", clk_i2c_p, 0,
> +			RK3568_CLKSEL_CON(23), 10, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(8), 4, GFLAGS),
> +	GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s3_2ch_tx", 0,
> +			RK3568_CLKGATE_CON(8), 5, GFLAGS),
> +	GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s3_2ch_rx", 0,
> +			RK3568_CLKGATE_CON(8), 6, GFLAGS),
> +
> +	/* PD_SECURE_FLASH */
> +	COMPOSITE_NODIV(ACLK_SECURE_FLASH, "aclk_secure_flash", gpll200_gpll150_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(27), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(8), 7, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_SECURE_FLASH, "hclk_secure_flash", gpll150_gpll100_gpll75_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(27), 2, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(8), 8, GFLAGS),
> +	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(8), 11, GFLAGS),
> +	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(8), 12, GFLAGS),
> +	COMPOSITE_NODIV(CLK_CRYPTO_NS_CORE, "clk_crypto_ns_core", gpll200_gpll150_gpll100_p, 0,
> +			RK3568_CLKSEL_CON(27), 4, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(8), 13, GFLAGS),
> +	COMPOSITE_NODIV(CLK_CRYPTO_NS_PKA, "clk_crypto_ns_pka", gpll300_gpll200_gpll100_p, 0,
> +			RK3568_CLKSEL_CON(27), 6, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(8), 14, GFLAGS),
> +	GATE(CLK_CRYPTO_NS_RNG, "clk_crypto_ns_rng", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(8), 15, GFLAGS),
> +	GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_flash", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(9), 10, GFLAGS),
> +	GATE(CLK_TRNG_NS, "clk_trng_ns", "hclk_secure_flash", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(9), 11, GFLAGS),
> +	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(26), 9, GFLAGS),
> +	GATE(CLK_OTPC_NS_SBPI, "clk_otpc_ns_sbpi", "xin24m", 0,
> +			RK3568_CLKGATE_CON(26), 10, GFLAGS),
> +	GATE(CLK_OTPC_NS_USR, "clk_otpc_ns_usr", "xin_osc0_half", 0,
> +			RK3568_CLKGATE_CON(26), 11, GFLAGS),
> +	GATE(HCLK_NANDC, "hclk_nandc", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(9), 0, GFLAGS),
> +	COMPOSITE_NODIV(NCLK_NANDC, "nclk_nandc", clk_nandc_p, 0,
> +			RK3568_CLKSEL_CON(28), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(9), 1, GFLAGS),
> +	GATE(HCLK_SFC, "hclk_sfc", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(9), 2, GFLAGS),
> +	GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(9), 3, GFLAGS),
> +	COMPOSITE_NODIV(SCLK_SFC, "sclk_sfc", sclk_sfc_p, 0,
> +			RK3568_CLKSEL_CON(28), 4, 3, MFLAGS,
> +			RK3568_CLKGATE_CON(9), 4, GFLAGS),
> +	GATE(ACLK_EMMC, "aclk_emmc", "aclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(9), 5, GFLAGS),
> +	GATE(HCLK_EMMC, "hclk_emmc", "hclk_secure_flash", 0,
> +			RK3568_CLKGATE_CON(9), 6, GFLAGS),
> +	COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", gpll200_gpll150_cpll125_p, 0,
> +			RK3568_CLKSEL_CON(28), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(9), 7, GFLAGS),
> +	COMPOSITE_NODIV(CCLK_EMMC, "cclk_emmc", cclk_emmc_p, 0,
> +			RK3568_CLKSEL_CON(28), 12, 3, MFLAGS,
> +			RK3568_CLKGATE_CON(9), 8, GFLAGS),
> +	GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0,
> +			RK3568_CLKGATE_CON(9), 9, GFLAGS),
> +	MMC(SCLK_EMMC_DRV, "emmc_drv", "cclk_emmc", RK3568_EMMC_CON0, 1),
> +	MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "cclk_emmc", RK3568_EMMC_CON1, 1),
> +
> +	/* PD_PIPE */
> +	COMPOSITE_NODIV(ACLK_PIPE, "aclk_pipe", aclk_pipe_p, 0,
> +			RK3568_CLKSEL_CON(29), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(10), 0, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_PIPE, "pclk_pipe", "aclk_pipe", 0,
> +			RK3568_CLKSEL_CON(29), 4, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(10), 1, GFLAGS),
> +	GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 0, GFLAGS),
> +	GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 1, GFLAGS),
> +	GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 2, GFLAGS),
> +	GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 3, GFLAGS),
> +	GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 0,
> +			RK3568_CLKGATE_CON(12), 4, GFLAGS),
> +	GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 8, GFLAGS),
> +	GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 9, GFLAGS),
> +	GATE(ACLK_PCIE30X1_DBI, "aclk_pcie30x1_dbi", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 10, GFLAGS),
> +	GATE(PCLK_PCIE30X1, "pclk_pcie30x1", "pclk_pipe", 0,
> +			RK3568_CLKGATE_CON(12), 11, GFLAGS),
> +	GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 0,
> +			RK3568_CLKGATE_CON(12), 12, GFLAGS),
> +	GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(13), 0, GFLAGS),
> +	GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(13), 1, GFLAGS),
> +	GATE(ACLK_PCIE30X2_DBI, "aclk_pcie30x2_dbi", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(13), 2, GFLAGS),
> +	GATE(PCLK_PCIE30X2, "pclk_pcie30x2", "pclk_pipe", 0,
> +			RK3568_CLKGATE_CON(13), 3, GFLAGS),
> +	GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 0,
> +			RK3568_CLKGATE_CON(13), 4, GFLAGS),
> +	GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(11), 0, GFLAGS),
> +	GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "gpll_20m", 0,
> +			RK3568_CLKGATE_CON(11), 1, GFLAGS),
> +	GATE(CLK_SATA0_RXOOB, "clk_sata0_rxoob", "cpll_50m", 0,
> +			RK3568_CLKGATE_CON(11), 2, GFLAGS),
> +	GATE(ACLK_SATA1, "aclk_sata1", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(11), 4, GFLAGS),
> +	GATE(CLK_SATA1_PMALIVE, "clk_sata1_pmalive", "gpll_20m", 0,
> +			RK3568_CLKGATE_CON(11), 5, GFLAGS),
> +	GATE(CLK_SATA1_RXOOB, "clk_sata1_rxoob", "cpll_50m", 0,
> +			RK3568_CLKGATE_CON(11), 6, GFLAGS),
> +	GATE(ACLK_SATA2, "aclk_sata2", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(11), 8, GFLAGS),
> +	GATE(CLK_SATA2_PMALIVE, "clk_sata2_pmalive", "gpll_20m", 0,
> +			RK3568_CLKGATE_CON(11), 9, GFLAGS),
> +	GATE(CLK_SATA2_RXOOB, "clk_sata2_rxoob", "cpll_50m", 0,
> +			RK3568_CLKGATE_CON(11), 10, GFLAGS),
> +	GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(10), 8, GFLAGS),
> +	GATE(CLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0,
> +			RK3568_CLKGATE_CON(10), 9, GFLAGS),
> +	COMPOSITE_NODIV(CLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", xin24m_32k_p, 0,
> +			RK3568_CLKSEL_CON(29), 8, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(10), 10, GFLAGS),
> +	GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_pipe", 0,
> +			RK3568_CLKGATE_CON(10), 12, GFLAGS),
> +	GATE(CLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0,
> +			RK3568_CLKGATE_CON(10), 13, GFLAGS),
> +	COMPOSITE_NODIV(CLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", xin24m_32k_p, 0,
> +			RK3568_CLKSEL_CON(29), 9, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(10), 14, GFLAGS),
> +	COMPOSITE_NODIV(CLK_XPCS_EEE, "clk_xpcs_eee", gpll200_cpll125_p, 0,
> +			RK3568_CLKSEL_CON(29), 13, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(10), 4, GFLAGS),
> +	GATE(PCLK_XPCS, "pclk_xpcs", "pclk_pipe", 0,
> +			RK3568_CLKGATE_CON(13), 6, GFLAGS),
> +
> +	/* PD_PHP */
> +	COMPOSITE_NODIV(ACLK_PHP, "aclk_php", gpll300_gpll200_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(30), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(14), 8, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_PHP, "hclk_php", gpll150_gpll100_gpll75_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(30), 2, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(14), 9, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_PHP, "pclk_php", "aclk_php", 0,
> +			RK3568_CLKSEL_CON(30), 4, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(14), 10, GFLAGS),
> +	GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_php", 0,
> +			RK3568_CLKGATE_CON(15), 0, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SDMMC0, "clk_sdmmc0", clk_sdmmc_p, 0,
> +			RK3568_CLKSEL_CON(30), 8, 3, MFLAGS,
> +			RK3568_CLKGATE_CON(15), 1, GFLAGS),
> +	MMC(SCLK_SDMMC0_DRV, "sdmmc0_drv", "clk_sdmmc0", RK3568_SDMMC0_CON0, 1),
> +	MMC(SCLK_SDMMC0_SAMPLE, "sdmmc0_sample", "clk_sdmmc0", RK3568_SDMMC0_CON1, 1),
> +
> +	GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_php", 0,
> +			RK3568_CLKGATE_CON(15), 2, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SDMMC1, "clk_sdmmc1", clk_sdmmc_p, 0,
> +			RK3568_CLKSEL_CON(30), 12, 3, MFLAGS,
> +			RK3568_CLKGATE_CON(15), 3, GFLAGS),
> +	MMC(SCLK_SDMMC1_DRV, "sdmmc1_drv", "clk_sdmmc1", RK3568_SDMMC1_CON0, 1),
> +	MMC(SCLK_SDMMC1_SAMPLE, "sdmmc1_sample", "clk_sdmmc1", RK3568_SDMMC1_CON1, 1),
> +
> +	GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_php", 0,
> +			RK3568_CLKGATE_CON(15), 5, GFLAGS),
> +	GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php", 0,
> +			RK3568_CLKGATE_CON(15), 6, GFLAGS),
> +	COMPOSITE_NODIV(CLK_MAC0_2TOP, "clk_mac0_2top", clk_mac_2top_p, 0,
> +			RK3568_CLKSEL_CON(31), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(15), 7, GFLAGS),
> +	COMPOSITE_NODIV(CLK_MAC0_OUT, "clk_mac0_out", cpll125_cpll50_cpll25_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(31), 14, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(15), 8, GFLAGS),
> +	GATE(CLK_MAC0_REFOUT, "clk_mac0_refout", "clk_mac0_2top", 0,
> +			RK3568_CLKGATE_CON(15), 12, GFLAGS),
> +	COMPOSITE_NODIV(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac_ptp_p, 0,
> +			RK3568_CLKSEL_CON(31), 12, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(15), 4, GFLAGS),
> +	MUX(SCLK_GMAC0, "clk_gmac0", mux_gmac0_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(31), 2, 1, MFLAGS),
> +	FACTOR(0, "clk_gmac0_tx_div5", "clk_gmac0", 0, 1, 5),
> +	FACTOR(0, "clk_gmac0_tx_div50", "clk_gmac0", 0, 1, 50),
> +	FACTOR(0, "clk_gmac0_rx_div2", "clk_gmac0", 0, 1, 2),
> +	FACTOR(0, "clk_gmac0_rx_div20", "clk_gmac0", 0, 1, 20),
> +	MUX(SCLK_GMAC0_RGMII_SPEED, "clk_gmac0_rgmii_speed", mux_gmac0_rgmii_speed_p, 0,
> +			RK3568_CLKSEL_CON(31), 4, 2, MFLAGS),
> +	MUX(SCLK_GMAC0_RMII_SPEED, "clk_gmac0_rmii_speed", mux_gmac0_rmii_speed_p, 0,
> +			RK3568_CLKSEL_CON(31), 3, 1, MFLAGS),
> +	MUX(SCLK_GMAC0_RX_TX, "clk_gmac0_rx_tx", mux_gmac0_rx_tx_p,  CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(31), 0, 2, MFLAGS),
> +
> +	/* PD_USB */
> +	COMPOSITE_NODIV(ACLK_USB, "aclk_usb", gpll300_gpll200_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(32), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(16), 0, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_USB, "hclk_usb", gpll150_gpll100_gpll75_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(32), 2, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(16), 1, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_USB, "pclk_usb", "aclk_usb", 0,
> +			RK3568_CLKSEL_CON(32), 4, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(16), 2, GFLAGS),
> +	GATE(HCLK_USB2HOST0, "hclk_usb2host0", "hclk_usb", 0,
> +			RK3568_CLKGATE_CON(16), 12, GFLAGS),
> +	GATE(HCLK_USB2HOST0_ARB, "hclk_usb2host0_arb", "hclk_usb", 0,
> +			RK3568_CLKGATE_CON(16), 13, GFLAGS),
> +	GATE(HCLK_USB2HOST1, "hclk_usb2host1", "hclk_usb", 0,
> +			RK3568_CLKGATE_CON(16), 14, GFLAGS),
> +	GATE(HCLK_USB2HOST1_ARB, "hclk_usb2host1_arb", "hclk_usb", 0,
> +			RK3568_CLKGATE_CON(16), 15, GFLAGS),
> +	GATE(HCLK_SDMMC2, "hclk_sdmmc2", "hclk_usb", 0,
> +			RK3568_CLKGATE_CON(17), 0, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SDMMC2, "clk_sdmmc2", clk_sdmmc_p, 0,
> +			RK3568_CLKSEL_CON(32), 8, 3, MFLAGS,
> +			RK3568_CLKGATE_CON(17), 1, GFLAGS),
> +	MMC(SCLK_SDMMC2_DRV, "sdmmc2_drv", "clk_sdmmc2", RK3568_SDMMC2_CON0, 1),
> +	MMC(SCLK_SDMMC2_SAMPLE, "sdmmc2_sample", "clk_sdmmc2", RK3568_SDMMC2_CON1, 1),
> +
> +	GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_usb", 0,
> +			RK3568_CLKGATE_CON(17), 3, GFLAGS),
> +	GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_usb", 0,
> +			RK3568_CLKGATE_CON(17), 4, GFLAGS),
> +	COMPOSITE_NODIV(CLK_MAC1_2TOP, "clk_mac1_2top", clk_mac_2top_p, 0,
> +			RK3568_CLKSEL_CON(33), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(17), 5, GFLAGS),
> +	COMPOSITE_NODIV(CLK_MAC1_OUT, "clk_mac1_out", cpll125_cpll50_cpll25_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(33), 14, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(17), 6, GFLAGS),
> +	GATE(CLK_MAC1_REFOUT, "clk_mac1_refout", "clk_mac1_2top", 0,
> +			RK3568_CLKGATE_CON(17), 10, GFLAGS),
> +	COMPOSITE_NODIV(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac_ptp_p, 0,
> +			RK3568_CLKSEL_CON(33), 12, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(17), 2, GFLAGS),
> +	MUX(SCLK_GMAC1, "clk_gmac1", mux_gmac1_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(33), 2, 1, MFLAGS),
> +	FACTOR(0, "clk_gmac1_tx_div5", "clk_gmac1", 0, 1, 5),
> +	FACTOR(0, "clk_gmac1_tx_div50", "clk_gmac1", 0, 1, 50),
> +	FACTOR(0, "clk_gmac1_rx_div2", "clk_gmac1", 0, 1, 2),
> +	FACTOR(0, "clk_gmac1_rx_div20", "clk_gmac1", 0, 1, 20),
> +	MUX(SCLK_GMAC1_RGMII_SPEED, "clk_gmac1_rgmii_speed", mux_gmac1_rgmii_speed_p, 0,
> +			RK3568_CLKSEL_CON(33), 4, 2, MFLAGS),
> +	MUX(SCLK_GMAC1_RMII_SPEED, "clk_gmac1_rmii_speed", mux_gmac1_rmii_speed_p, 0,
> +			RK3568_CLKSEL_CON(33), 3, 1, MFLAGS),
> +	MUX(SCLK_GMAC1_RX_TX, "clk_gmac1_rx_tx", mux_gmac1_rx_tx_p,  CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(33), 0, 2, MFLAGS),
> +
> +	/* PD_PERI */
> +	COMPOSITE_NODIV(ACLK_PERIMID, "aclk_perimid", gpll300_gpll200_gpll100_xin24m_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(10), 4, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(14), 0, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_PERIMID, "hclk_perimid", gpll150_gpll100_gpll75_xin24m_p, CLK_IGNORE_UNUSED,
> +			RK3568_CLKSEL_CON(10), 6, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(14), 1, GFLAGS),
> +
> +	/* PD_VI */
> +	COMPOSITE_NODIV(ACLK_VI, "aclk_vi", gpll400_gpll300_gpll200_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(34), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(18), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_VI, "hclk_vi", "aclk_vi", 0,
> +			RK3568_CLKSEL_CON(34), 4, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(18), 1, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_VI, "pclk_vi", "aclk_vi", 0,
> +			RK3568_CLKSEL_CON(34), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(18), 2, GFLAGS),
> +	GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi", 0,
> +			RK3568_CLKGATE_CON(18), 9, GFLAGS),
> +	GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 0,
> +			RK3568_CLKGATE_CON(18), 10, GFLAGS),
> +	COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", cpll333_gpll300_gpll200_p, 0,
> +			RK3568_CLKSEL_CON(34), 14, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(18), 11, GFLAGS),
> +	GATE(ICLK_VICAP_G, "iclk_vicap_g", "iclk_vicap", 0,
> +			RK3568_CLKGATE_CON(18), 13, GFLAGS),
> +	GATE(ACLK_ISP, "aclk_isp", "aclk_vi", 0,
> +			RK3568_CLKGATE_CON(19), 0, GFLAGS),
> +	GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 0,
> +			RK3568_CLKGATE_CON(19), 1, GFLAGS),
> +	COMPOSITE(CLK_ISP, "clk_isp", cpll_gpll_hpll_p, 0,
> +			RK3568_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(19), 2, GFLAGS),
> +	GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi", 0,
> +			RK3568_CLKGATE_CON(19), 4, GFLAGS),
> +	COMPOSITE(CLK_CIF_OUT, "clk_cif_out", gpll_usb480m_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(19), 8, GFLAGS),
> +	COMPOSITE(CLK_CAM0_OUT, "clk_cam0_out", gpll_usb480m_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(19), 9, GFLAGS),
> +	COMPOSITE(CLK_CAM1_OUT, "clk_cam1_out", gpll_usb480m_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 6, DFLAGS,
> +			RK3568_CLKGATE_CON(19), 10, GFLAGS),
> +
> +	/* PD_VO */
> +	COMPOSITE_NODIV(ACLK_VO, "aclk_vo", gpll300_cpll250_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(37), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(20), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_VO, "hclk_vo", "aclk_vo", 0,
> +			RK3568_CLKSEL_CON(37), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 1, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_VO, "pclk_vo", "aclk_vo", 0,
> +			RK3568_CLKSEL_CON(37), 12, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 2, GFLAGS),
> +	COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", cpll_gpll_hpll_vpll_p, 0,
> +			RK3568_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 6, GFLAGS),
> +	GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0,
> +			RK3568_CLKGATE_CON(20), 8, GFLAGS),
> +	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
> +			RK3568_CLKGATE_CON(20), 9, GFLAGS),
> +	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 10, GFLAGS),
> +	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 11, GFLAGS),
> +	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
> +			RK3568_CLKGATE_CON(20), 12, GFLAGS),
> +	GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
> +			RK3568_CLKGATE_CON(20), 13, GFLAGS),
> +	GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 0, GFLAGS),
> +	GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 1, GFLAGS),
> +	GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 2, GFLAGS),
> +	GATE(PCLK_HDMI_HOST, "pclk_hdmi_host", "pclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 3, GFLAGS),
> +	GATE(CLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0,
> +			RK3568_CLKGATE_CON(21), 4, GFLAGS),
> +	GATE(CLK_HDMI_CEC, "clk_hdmi_cec", "clk_rtc_32k", 0,
> +			RK3568_CLKGATE_CON(21), 5, GFLAGS),
> +	GATE(PCLK_DSITX_0, "pclk_dsitx_0", "pclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 6, GFLAGS),
> +	GATE(PCLK_DSITX_1, "pclk_dsitx_1", "pclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 7, GFLAGS),
> +	GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_vo", 0,
> +			RK3568_CLKGATE_CON(21), 8, GFLAGS),
> +	COMPOSITE_NODIV(CLK_EDP_200M, "clk_edp_200m", gpll200_gpll150_cpll125_p, 0,
> +			RK3568_CLKSEL_CON(38), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(21), 9, GFLAGS),
> +
> +	/* PD_VPU */
> +	COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(42), 7, 1, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(22), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0,
> +			RK3568_CLKSEL_CON(42), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(22), 1, GFLAGS),
> +	GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0,
> +			RK3568_CLKGATE_CON(22), 4, GFLAGS),
> +	GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0,
> +			RK3568_CLKGATE_CON(22), 5, GFLAGS),
> +
> +	/* PD_RGA */
> +	COMPOSITE_NODIV(ACLK_RGA_PRE, "aclk_rga_pre", gpll300_cpll250_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(43), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(23), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_RGA_PRE, "hclk_rga_pre", "aclk_rga_pre", 0,
> +			RK3568_CLKSEL_CON(43), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(23), 1, GFLAGS),
> +	COMPOSITE_NOMUX(PCLK_RGA_PRE, "pclk_rga_pre", "aclk_rga_pre", 0,
> +			RK3568_CLKSEL_CON(43), 12, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(22), 12, GFLAGS),
> +	GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 4, GFLAGS),
> +	GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 5, GFLAGS),
> +	COMPOSITE_NODIV(CLK_RGA_CORE, "clk_rga_core", gpll300_gpll200_gpll100_p, 0,
> +			RK3568_CLKSEL_CON(43), 2, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(23), 6, GFLAGS),
> +	GATE(ACLK_IEP, "aclk_iep", "aclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 7, GFLAGS),
> +	GATE(HCLK_IEP, "hclk_iep", "hclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 8, GFLAGS),
> +	COMPOSITE_NODIV(CLK_IEP_CORE, "clk_iep_core", gpll300_gpll200_gpll100_p, 0,
> +			RK3568_CLKSEL_CON(43), 4, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(23), 9, GFLAGS),
> +	GATE(HCLK_EBC, "hclk_ebc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 10, GFLAGS),
> +	COMPOSITE_NODIV(DCLK_EBC, "dclk_ebc", gpll400_cpll333_gpll200_p, 0,
> +			RK3568_CLKSEL_CON(43), 6, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(23), 11, GFLAGS),
> +	GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 12, GFLAGS),
> +	GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 13, GFLAGS),
> +	GATE(ACLK_JENC, "aclk_jenc", "aclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 14, GFLAGS),
> +	GATE(HCLK_JENC, "hclk_jenc", "hclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(23), 15, GFLAGS),
> +	GATE(PCLK_EINK, "pclk_eink", "pclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(22), 14, GFLAGS),
> +	GATE(HCLK_EINK, "hclk_eink", "hclk_rga_pre", 0,
> +			RK3568_CLKGATE_CON(22), 15, GFLAGS),
> +
> +	/* PD_RKVENC */
> +	COMPOSITE(ACLK_RKVENC_PRE, "aclk_rkvenc_pre", gpll_cpll_npll_p, 0,
> +			RK3568_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(24), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_RKVENC_PRE, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0,
> +			RK3568_CLKSEL_CON(44), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(24), 1, GFLAGS),
> +	GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0,
> +			RK3568_CLKGATE_CON(24), 6, GFLAGS),
> +	GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0,
> +			RK3568_CLKGATE_CON(24), 7, GFLAGS),
> +	COMPOSITE(CLK_RKVENC_CORE, "clk_rkvenc_core", gpll_cpll_npll_vpll_p, 0,
> +			RK3568_CLKSEL_CON(45), 14, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(24), 8, GFLAGS),
> +	COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", aclk_rkvdec_pre_p, CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(47), 7, 1, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(25), 0, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0,
> +			RK3568_CLKSEL_CON(47), 8, 4, DFLAGS,
> +			RK3568_CLKGATE_CON(25), 1, GFLAGS),
> +	GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0,
> +			RK3568_CLKGATE_CON(25), 4, GFLAGS),
> +	GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0,
> +			RK3568_CLKGATE_CON(25), 5, GFLAGS),
> +	COMPOSITE(CLK_RKVDEC_CA, "clk_rkvdec_ca", gpll_cpll_npll_vpll_p, 0,
> +			RK3568_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(25), 6, GFLAGS),
> +	COMPOSITE(CLK_RKVDEC_CORE, "clk_rkvdec_core", clk_rkvdec_core_p, CLK_SET_RATE_NO_REPARENT,
> +			RK3568_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(25), 7, GFLAGS),
> +	COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_npll_vpll_p, 0,
> +			RK3568_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(25), 8, GFLAGS),
> +
> +	/* PD_BUS */
> +	COMPOSITE_NODIV(ACLK_BUS, "aclk_bus", gpll200_gpll150_gpll100_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(50), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(26), 0, GFLAGS),
> +	COMPOSITE_NODIV(PCLK_BUS, "pclk_bus", gpll100_gpll75_cpll50_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(50), 4, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(26), 1, GFLAGS),
> +	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(26), 4, GFLAGS),
> +	COMPOSITE(CLK_TSADC_TSEN, "clk_tsadc_tsen", xin24m_gpll100_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(51), 4, 2, MFLAGS, 0, 3, DFLAGS,
> +			RK3568_CLKGATE_CON(26), 5, GFLAGS),
> +	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "clk_tsadc_tsen", 0,
> +			RK3568_CLKSEL_CON(51), 8, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(26), 6, GFLAGS),
> +	GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(26), 7, GFLAGS),
> +	GATE(CLK_SARADC, "clk_saradc", "xin24m", 0,
> +			RK3568_CLKGATE_CON(26), 8, GFLAGS),
> +	GATE(PCLK_SCR, "pclk_scr", "pclk_bus", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(26), 12, GFLAGS),
> +	GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(26), 13, GFLAGS),
> +	GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0,
> +			RK3568_CLKGATE_CON(26), 14, GFLAGS),
> +	GATE(ACLK_MCU, "aclk_mcu", "aclk_bus", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(32), 13, GFLAGS),
> +	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus", CLK_IGNORE_UNUSED,
> +			RK3568_CLKGATE_CON(32), 14, GFLAGS),
> +	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(32), 15, GFLAGS),
> +
> +	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(27), 12, GFLAGS),
> +	COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(27), 13, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(53), 0,
> +			RK3568_CLKGATE_CON(27), 14, GFLAGS,
> +			&rk3568_uart1_fracmux),
> +	GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_mux", 0,
> +			RK3568_CLKGATE_CON(27), 15, GFLAGS),
> +
> +	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(28), 0, GFLAGS),
> +	COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(28), 1, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(55), 0,
> +			RK3568_CLKGATE_CON(28), 2, GFLAGS,
> +			&rk3568_uart2_fracmux),
> +	GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_mux", 0,
> +			RK3568_CLKGATE_CON(28), 3, GFLAGS),
> +
> +	GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(28), 4, GFLAGS),
> +	COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(28), 5, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(57), 0,
> +			RK3568_CLKGATE_CON(28), 6, GFLAGS,
> +			&rk3568_uart3_fracmux),
> +	GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_mux", 0,
> +			RK3568_CLKGATE_CON(28), 7, GFLAGS),
> +
> +	GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(28), 8, GFLAGS),
> +	COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(28), 9, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(59), 0,
> +			RK3568_CLKGATE_CON(28), 10, GFLAGS,
> +			&rk3568_uart4_fracmux),
> +	GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_mux", 0,
> +			RK3568_CLKGATE_CON(28), 11, GFLAGS),
> +
> +	GATE(PCLK_UART5, "pclk_uart5", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(28), 12, GFLAGS),
> +	COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(28), 13, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(61), 0,
> +			RK3568_CLKGATE_CON(28), 14, GFLAGS,
> +			&rk3568_uart5_fracmux),
> +	GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_mux", 0,
> +			RK3568_CLKGATE_CON(28), 15, GFLAGS),
> +
> +	GATE(PCLK_UART6, "pclk_uart6", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(29), 0, GFLAGS),
> +	COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(29), 1, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(63), 0,
> +			RK3568_CLKGATE_CON(29), 2, GFLAGS,
> +			&rk3568_uart6_fracmux),
> +	GATE(SCLK_UART6, "sclk_uart6", "sclk_uart6_mux", 0,
> +			RK3568_CLKGATE_CON(29), 3, GFLAGS),
> +
> +	GATE(PCLK_UART7, "pclk_uart7", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(29), 4, GFLAGS),
> +	COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(29), 5, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(65), 0,
> +			RK3568_CLKGATE_CON(29), 6, GFLAGS,
> +			&rk3568_uart7_fracmux),
> +	GATE(SCLK_UART7, "sclk_uart7", "sclk_uart7_mux", 0,
> +			RK3568_CLKGATE_CON(29), 7, GFLAGS),
> +
> +	GATE(PCLK_UART8, "pclk_uart8", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(29), 8, GFLAGS),
> +	COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(29), 9, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(67), 0,
> +			RK3568_CLKGATE_CON(29), 10, GFLAGS,
> +			&rk3568_uart8_fracmux),
> +	GATE(SCLK_UART8, "sclk_uart8", "sclk_uart8_mux", 0,
> +			RK3568_CLKGATE_CON(29), 11, GFLAGS),
> +
> +	GATE(PCLK_UART9, "pclk_uart9", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(29), 12, GFLAGS),
> +	COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_usb480m_p, 0,
> +			RK3568_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_CLKGATE_CON(29), 13, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", CLK_SET_RATE_PARENT,
> +			RK3568_CLKSEL_CON(69), 0,
> +			RK3568_CLKGATE_CON(29), 14, GFLAGS,
> +			&rk3568_uart9_fracmux),
> +	GATE(SCLK_UART9, "sclk_uart9", "sclk_uart9_mux", 0,
> +			RK3568_CLKGATE_CON(29), 15, GFLAGS),
> +
> +	GATE(PCLK_CAN0, "pclk_can0", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(27), 5, GFLAGS),
> +	COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(70), 7, 1, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(27), 6, GFLAGS),
> +	GATE(PCLK_CAN1, "pclk_can1", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(27), 7, GFLAGS),
> +	COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(70), 15, 1, MFLAGS, 8, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(27), 8, GFLAGS),
> +	GATE(PCLK_CAN2, "pclk_can2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(27), 9, GFLAGS),
> +	COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0,
> +			RK3568_CLKSEL_CON(71), 7, 1, MFLAGS, 0, 5, DFLAGS,
> +			RK3568_CLKGATE_CON(27), 10, GFLAGS),
> +	COMPOSITE_NODIV(CLK_I2C, "clk_i2c", clk_i2c_p, 0,
> +			RK3568_CLKSEL_CON(71), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(32), 10, GFLAGS),
> +	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 0, GFLAGS),
> +	GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 0,
> +			RK3568_CLKGATE_CON(30), 1, GFLAGS),
> +	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 2, GFLAGS),
> +	GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 0,
> +			RK3568_CLKGATE_CON(30), 3, GFLAGS),
> +	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 4, GFLAGS),
> +	GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 0,
> +			RK3568_CLKGATE_CON(30), 5, GFLAGS),
> +	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 6, GFLAGS),
> +	GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 0,
> +			RK3568_CLKGATE_CON(30), 7, GFLAGS),
> +	GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 8, GFLAGS),
> +	GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 0,
> +			RK3568_CLKGATE_CON(30), 9, GFLAGS),
> +	GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 10, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", gpll200_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 0, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(30), 11, GFLAGS),
> +	GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 12, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", gpll200_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 2, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(30), 13, GFLAGS),
> +	GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(30), 14, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", gpll200_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 4, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(30), 15, GFLAGS),
> +	GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 0, GFLAGS),
> +	COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", gpll200_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 6, 1, MFLAGS, RK3568_CLKGATE_CON(31), 1, GFLAGS),
> +	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 10, GFLAGS),
> +	COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", gpll100_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 8, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(31), 11, GFLAGS),
> +	GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0,
> +			RK3568_CLKGATE_CON(31), 12, GFLAGS),
> +	GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 13, GFLAGS),
> +	COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", gpll100_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 10, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(31), 14, GFLAGS),
> +	GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0,
> +			RK3568_CLKGATE_CON(31), 15, GFLAGS),
> +	GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(32), 0, GFLAGS),
> +	COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", gpll100_xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(72), 12, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(32), 1, GFLAGS),
> +	GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 2, GFLAGS),
> +	COMPOSITE_NODIV(DBCLK_GPIO, "dbclk_gpio", xin24m_32k_p, 0,
> +			RK3568_CLKSEL_CON(72), 14, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(32), 11, GFLAGS),
> +	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 2, GFLAGS),
> +	GATE(DBCLK_GPIO1, "dbclk_gpio1", "dbclk_gpio", 0,
> +			RK3568_CLKGATE_CON(31), 3, GFLAGS),
> +	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 4, GFLAGS),
> +	GATE(DBCLK_GPIO2, "dbclk_gpio2", "dbclk_gpio", 0,
> +			RK3568_CLKGATE_CON(31), 5, GFLAGS),
> +	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 6, GFLAGS),
> +	GATE(DBCLK_GPIO3, "dbclk_gpio3", "dbclk_gpio", 0,
> +			RK3568_CLKGATE_CON(31), 7, GFLAGS),
> +	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(31), 8, GFLAGS),
> +	GATE(DBCLK_GPIO4, "dbclk_gpio4", "dbclk_gpio", 0,
> +			RK3568_CLKGATE_CON(31), 9, GFLAGS),
> +	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0,
> +			RK3568_CLKGATE_CON(32), 3, GFLAGS),
> +	GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 4, GFLAGS),
> +	GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 5, GFLAGS),
> +	GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 6, GFLAGS),
> +	GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 7, GFLAGS),
> +	GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 8, GFLAGS),
> +	GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0,
> +			RK3568_CLKGATE_CON(32), 9, GFLAGS),
> +
> +	/* PD_TOP */
> +	COMPOSITE_NODIV(ACLK_TOP_HIGH, "aclk_top_high", cpll500_gpll400_gpll300_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(73), 0, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(33), 0, GFLAGS),
> +	COMPOSITE_NODIV(ACLK_TOP_LOW, "aclk_top_low", gpll400_gpll300_gpll200_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(73), 4, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(33), 1, GFLAGS),
> +	COMPOSITE_NODIV(HCLK_TOP, "hclk_top", gpll150_gpll100_gpll75_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(73), 8, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(33), 2, GFLAGS),
> +	COMPOSITE_NODIV(PCLK_TOP, "pclk_top", gpll100_gpll75_cpll50_xin24m_p, 0,
> +			RK3568_CLKSEL_CON(73), 12, 2, MFLAGS,
> +			RK3568_CLKGATE_CON(33), 3, GFLAGS),
> +	GATE(PCLK_PCIE30PHY, "pclk_pcie30phy", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(33), 8, GFLAGS),
> +	COMPOSITE_NODIV(CLK_OPTC_ARB, "clk_optc_arb", xin24m_cpll100_p, 0,
> +			RK3568_CLKSEL_CON(73), 15, 1, MFLAGS,
> +			RK3568_CLKGATE_CON(33), 9, GFLAGS),
> +	GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(33), 13, GFLAGS),
> +	GATE(PCLK_MIPIDSIPHY0, "pclk_mipidsiphy0", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(33), 14, GFLAGS),
> +	GATE(PCLK_MIPIDSIPHY1, "pclk_mipidsiphy1", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(33), 15, GFLAGS),
> +	GATE(PCLK_PIPEPHY0, "pclk_pipephy0", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 4, GFLAGS),
> +	GATE(PCLK_PIPEPHY1, "pclk_pipephy1", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 5, GFLAGS),
> +	GATE(PCLK_PIPEPHY2, "pclk_pipephy2", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 6, GFLAGS),
> +	GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 11, GFLAGS),
> +	GATE(CLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 0,
> +			RK3568_CLKGATE_CON(34), 12, GFLAGS),
> +	GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 13, GFLAGS),
> +	GATE(PCLK_EDPPHY_GRF, "pclk_edpphy_grf", "pclk_top", 0,
> +			RK3568_CLKGATE_CON(34), 14, GFLAGS),
> +};
> +
> +static struct rockchip_clk_branch rk3568_clk_pmu_branches[] __initdata = {
> +	/* PD_PMU */
> +	FACTOR(0, "ppll_ph0", "ppll", 0, 1, 2),
> +	FACTOR(0, "ppll_ph180", "ppll", 0, 1, 2),
> +	FACTOR(0, "hpll_ph0", "hpll", 0, 1, 2),
> +
> +	MUX(CLK_PDPMU, "clk_pdpmu", clk_pdpmu_p, 0,
> +			RK3568_PMU_CLKSEL_CON(2), 15, 1, MFLAGS),
> +	COMPOSITE_NOMUX(PCLK_PDPMU, "pclk_pdpmu", "clk_pdpmu", 0,
> +			RK3568_PMU_CLKSEL_CON(2), 0, 5, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(0), 2, GFLAGS),
> +	GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(0), 6, GFLAGS),
> +	GATE(CLK_PMU, "clk_pmu", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(0), 7, GFLAGS),
> +	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 0, GFLAGS),
> +	COMPOSITE_NOMUX(CLK_I2C0, "clk_i2c0", "clk_pdpmu", 0,
> +			RK3568_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(1), 1, GFLAGS),
> +	GATE(PCLK_UART0, "pclk_uart0", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 2, GFLAGS),
> +
> +	COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED,
> +			RK3568_PMU_CLKSEL_CON(1), 0,
> +			RK3568_PMU_CLKGATE_CON(0), 1, GFLAGS,
> +			&rk3568_rtc32k_pmu_fracmux),
> +
> +	COMPOSITE_NOMUX(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", CLK_IGNORE_UNUSED,
> +			RK3568_PMU_CLKSEL_CON(0), 0, 5, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(0), 0, GFLAGS),
> +
> +	COMPOSITE(CLK_UART0_DIV, "sclk_uart0_div", ppll_usb480m_cpll_gpll_p, 0,
> +			RK3568_PMU_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(1), 3, GFLAGS),
> +	COMPOSITE_FRACMUX(CLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_div", CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(5), 0,
> +			RK3568_PMU_CLKGATE_CON(1), 4, GFLAGS,
> +			&rk3568_uart0_fracmux),
> +	GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 5, GFLAGS),
> +
> +	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 9, GFLAGS),
> +	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", xin24m_32k_p, 0,
> +			RK3568_PMU_CLKSEL_CON(6), 15, 1, MFLAGS,
> +			RK3568_PMU_CLKGATE_CON(1), 10, GFLAGS),
> +	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 6, GFLAGS),
> +	COMPOSITE(CLK_PWM0, "clk_pwm0", clk_pwm0_p, 0,
> +			RK3568_PMU_CLKSEL_CON(6), 7, 1, MFLAGS, 0, 7, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(1), 7, GFLAGS),
> +	GATE(CLK_CAPTURE_PWM0_NDFT, "clk_capture_pwm0_ndft", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 8, GFLAGS),
> +	GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 11, GFLAGS),
> +	GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 12, GFLAGS),
> +	GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(1), 13, GFLAGS),
> +	COMPOSITE_NOMUX(CLK_REF24M, "clk_ref24m", "clk_pdpmu", 0,
> +			RK3568_PMU_CLKSEL_CON(7), 0, 6, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(2), 0, GFLAGS),
> +	GATE(XIN_OSC0_USBPHY0_G, "xin_osc0_usbphy0_g", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 1, GFLAGS),
> +	MUX(CLK_USBPHY0_REF, "clk_usbphy0_ref", clk_usbphy0_ref_p, 0,
> +			RK3568_PMU_CLKSEL_CON(8), 0, 1, MFLAGS),
> +	GATE(XIN_OSC0_USBPHY1_G, "xin_osc0_usbphy1_g", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 2, GFLAGS),
> +	MUX(CLK_USBPHY1_REF, "clk_usbphy1_ref", clk_usbphy1_ref_p, 0,
> +			RK3568_PMU_CLKSEL_CON(8), 1, 1, MFLAGS),
> +	GATE(XIN_OSC0_MIPIDSIPHY0_G, "xin_osc0_mipidsiphy0_g", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 3, GFLAGS),
> +	MUX(CLK_MIPIDSIPHY0_REF, "clk_mipidsiphy0_ref", clk_mipidsiphy0_ref_p, 0,
> +			RK3568_PMU_CLKSEL_CON(8), 2, 1, MFLAGS),
> +	GATE(XIN_OSC0_MIPIDSIPHY1_G, "xin_osc0_mipidsiphy1_g", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 4, GFLAGS),
> +	MUX(CLK_MIPIDSIPHY1_REF, "clk_mipidsiphy1_ref", clk_mipidsiphy1_ref_p, 0,
> +			RK3568_PMU_CLKSEL_CON(8), 3, 1, MFLAGS),
> +	COMPOSITE_NOMUX(CLK_WIFI_DIV, "clk_wifi_div", "clk_pdpmu", 0,
> +			RK3568_PMU_CLKSEL_CON(8), 8, 6, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(2), 5, GFLAGS),
> +	GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 6, GFLAGS),
> +	MUX(CLK_WIFI, "clk_wifi", clk_wifi_p, CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(8), 15, 1, MFLAGS),
> +	COMPOSITE_NOMUX(CLK_PCIEPHY0_DIV, "clk_pciephy0_div", "ppll_ph0", 0,
> +			RK3568_PMU_CLKSEL_CON(9), 0, 3, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(2), 7, GFLAGS),
> +	GATE(CLK_PCIEPHY0_OSC0, "clk_pciephy0_osc0", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 8, GFLAGS),
> +	MUX(CLK_PCIEPHY0_REF, "clk_pciephy0_ref", clk_pciephy0_ref_p, CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(9), 3, 1, MFLAGS),
> +	COMPOSITE_NOMUX(CLK_PCIEPHY1_DIV, "clk_pciephy1_div", "ppll_ph0", 0,
> +			RK3568_PMU_CLKSEL_CON(9), 4, 3, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(2), 9, GFLAGS),
> +	GATE(CLK_PCIEPHY1_OSC0, "clk_pciephy1_osc0", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 10, GFLAGS),
> +	MUX(CLK_PCIEPHY1_REF, "clk_pciephy1_ref", clk_pciephy1_ref_p, CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(9), 7, 1, MFLAGS),
> +	COMPOSITE_NOMUX(CLK_PCIEPHY2_DIV, "clk_pciephy2_div", "ppll_ph0", 0,
> +			RK3568_PMU_CLKSEL_CON(9), 8, 3, DFLAGS,
> +			RK3568_PMU_CLKGATE_CON(2), 11, GFLAGS),
> +	GATE(CLK_PCIEPHY2_OSC0, "clk_pciephy2_osc0", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 12, GFLAGS),
> +	MUX(CLK_PCIEPHY2_REF, "clk_pciephy2_ref", clk_pciephy2_ref_p, CLK_SET_RATE_PARENT,
> +			RK3568_PMU_CLKSEL_CON(9), 11, 1, MFLAGS),
> +	GATE(CLK_PCIE30PHY_REF_M, "clk_pcie30phy_ref_m", "ppll_ph0", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 13, GFLAGS),
> +	GATE(CLK_PCIE30PHY_REF_N, "clk_pcie30phy_ref_n", "ppll_ph180", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS),
> +	GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0,
> +			RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS),
> +	MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0,
> +			RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS),
> +};
> +
> +static const char *const rk3568_cru_critical_clocks[] __initconst = {
> +	"armclk",
> +	"pclk_core_pre",
> +	"aclk_bus",
> +	"pclk_bus",
> +	"aclk_top_high",
> +	"aclk_top_low",
> +	"hclk_top",
> +	"pclk_top",
> +	"aclk_perimid",
> +	"hclk_perimid",
> +	"aclk_secure_flash",
> +	"hclk_secure_flash",
> +	"aclk_core_niu2bus",
> +	"npll",
> +	"clk_optc_arb",
> +	"hclk_php",
> +	"pclk_php",
> +	"hclk_usb",
> +};
> +
> +static const char *const rk3568_pmucru_critical_clocks[] __initconst = {
> +	"pclk_pdpmu",
> +	"pclk_pmu",
> +	"clk_pmu",
> +};
> +
> +static void __init rk3568_pmu_clk_init(struct device_node *np)
> +{
> +	struct rockchip_clk_provider *ctx;
> +	void __iomem *reg_base;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base) {
> +		pr_err("%s: could not map cru pmu region\n", __func__);
> +		return;
> +	}
> +
> +	ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
> +	if (IS_ERR(ctx)) {
> +		pr_err("%s: rockchip pmu clk init failed\n", __func__);
> +		return;
> +	}
> +
> +	rockchip_clk_register_plls(ctx, rk3568_pmu_pll_clks,
> +				   ARRAY_SIZE(rk3568_pmu_pll_clks),
> +				   RK3568_GRF_SOC_STATUS0);
> +
> +	rockchip_clk_register_branches(ctx, rk3568_clk_pmu_branches,
> +				       ARRAY_SIZE(rk3568_clk_pmu_branches));
> +
> +	rockchip_clk_protect_critical(rk3568_pmucru_critical_clocks,
> +				      ARRAY_SIZE(rk3568_pmucru_critical_clocks));

Upstream patch is registering system restart handler here. While it seems it can be
done with a syscon-reboot node (and enabled driver) in the device tree, registering
it here may save some time when updating the driver in future.

> +
> +	rockchip_clk_of_add_provider(np, ctx);
> +}
> +
> +static void __init rk3568_clk_init(struct device_node *np)
> +{
> +	struct rockchip_clk_provider *ctx;
> +	void __iomem *reg_base;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base) {
> +		pr_err("%s: could not map cru region\n", __func__);
> +		return;
> +	}
> +
> +	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
> +	if (IS_ERR(ctx)) {
> +		pr_err("%s: rockchip clk init failed\n", __func__);
> +		return;
> +	}
> +
> +	rockchip_clk_register_plls(ctx, rk3568_pll_clks,
> +				   ARRAY_SIZE(rk3568_pll_clks),
> +				   RK3568_GRF_SOC_STATUS0);
> +
> +	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
> +				     mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
> +				     &rk3568_cpuclk_data, rk3568_cpuclk_rates,
> +				     ARRAY_SIZE(rk3568_cpuclk_rates));
> +
> +	rockchip_clk_register_branches(ctx, rk3568_clk_branches,
> +				       ARRAY_SIZE(rk3568_clk_branches));
> +
> +	rockchip_clk_protect_critical(rk3568_cru_critical_clocks,
> +				      ARRAY_SIZE(rk3568_cru_critical_clocks));

The upstream patch registers the softrst reset controller here, which you do not.
On previous rockchip SoCs, it was necessary for releasing the MAC out of reset
and it seems to be the case for the rk3568 as well. What's is currently
toggling the reset for you?

> +
> +	rockchip_clk_of_add_provider(np, ctx);
> +}
> +
> +struct clk_rk3568_inits {
> +	void (*inits)(struct device_node *np);
> +};
> +
> +static const struct clk_rk3568_inits clk_rk3568_pmucru_init = {
> +	.inits = rk3568_pmu_clk_init,
> +};
> +
> +static const struct clk_rk3568_inits clk_3568_cru_init = {
> +	.inits = rk3568_clk_init,
> +};
> +
> +static const struct of_device_id clk_rk3568_match_table[] = {
> +	{
> +		.compatible = "rockchip,rk3568-cru",
> +		.data = &clk_3568_cru_init,
> +	},  {
> +		.compatible = "rockchip,rk3568-pmucru",
> +		.data = &clk_rk3568_pmucru_init,
> +	},
> +	{ }
> +};
> +
> +static int __init clk_rk3568_probe(struct device_d *dev)
> +{
> +	struct device_node *np = dev->device_node;
> +	const struct clk_rk3568_inits *init_data;
> +
> +	init_data = of_device_get_match_data(dev);
> +	if (init_data->inits)
> +		init_data->inits(np);
> +
> +	return 0;
> +}
> +
> +static struct driver_d clk_rk3568_driver = {
> +	.probe  = clk_rk3568_probe,
> +	.name   = "clk-rk3568",
> +	.of_compatible = DRV_OF_COMPAT(clk_rk3568_match_table),
> +};
> +
> +core_platform_driver(clk_rk3568_driver);
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-02  9:54 ` [PATCH 04/24] clk: introduce struct clk_hw Sascha Hauer
@ 2021-06-11  7:55   ` Ahmad Fatoum
  2021-06-11  8:41     ` Sascha Hauer
  0 siblings, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-06-11  7:55 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

Hello Sascha,

On 02.06.21 11:54, Sascha Hauer wrote:

> In Linux the ops in struct clk_ops take a struct clk_hw * argument

> instead of a struct clk * argument as in barebox. With this taking

> new clk drivers from Linux requires a lot of mechanical conversions.

> Instead of doing this over and over again swallow the pill once and

> convert the existing barebox code over to clk_hw.

> 

> The implementation is a little different from Linux. In Linux struct clk

> is only known to the core clock code. In barebox struct clk is

> publically known and it is embedded into struct clk_hw. This allows

> us to still use struct clk members in the clock drivers which we

> currently still need, because otherwise this patch would be even

> bigger.

> 

> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

drivers/clk/sifive, which was added recently doesn't have these changes
and thus the build fails. To reproduce, without installed RISC-V toolchain, try:

   ./test/emulate.pl --runtime=podman sifive_defconfig

Doing the conversions aren't completely trivial to me, as there are no
clkdev clk_hw helpers ported and I still need to figure out how to use them.
Given that your caches are still hot, could you take a look?

Thanks,
Ahmad

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-11  7:55   ` Ahmad Fatoum
@ 2021-06-11  8:41     ` Sascha Hauer
  2021-06-11  9:19       ` Ahmad Fatoum
  0 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-11  8:41 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On Fri, Jun 11, 2021 at 09:55:36AM +0200, Ahmad Fatoum wrote:
> Hello Sascha,
> 
> On 02.06.21 11:54, Sascha Hauer wrote:
> 
> > In Linux the ops in struct clk_ops take a struct clk_hw * argument
> 
> > instead of a struct clk * argument as in barebox. With this taking
> 
> > new clk drivers from Linux requires a lot of mechanical conversions.
> 
> > Instead of doing this over and over again swallow the pill once and
> 
> > convert the existing barebox code over to clk_hw.
> 
> > 
> 
> > The implementation is a little different from Linux. In Linux struct clk
> 
> > is only known to the core clock code. In barebox struct clk is
> 
> > publically known and it is embedded into struct clk_hw. This allows
> 
> > us to still use struct clk members in the clock drivers which we
> 
> > currently still need, because otherwise this patch would be even
> 
> > bigger.
> 
> > 
> 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> 
> drivers/clk/sifive, which was added recently doesn't have these changes
> and thus the build fails. To reproduce, without installed RISC-V toolchain, try:
> 
>    ./test/emulate.pl --runtime=podman sifive_defconfig

Can't exec "tuxmake": No such file or directory at ./test/emulate.pl line 377.

Where do I get this from?

> 
> Doing the conversions aren't completely trivial to me, as there are no
> clkdev clk_hw helpers ported and I still need to figure out how to use them.
> Given that your caches are still hot, could you take a look?

Here we go. I added the following to next.

Sascha

---------------------------8<--------------------------------

>From 61da1fea5d3c516d7f2609daebfc19e035a4c485 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Fri, 11 Jun 2021 10:38:27 +0200
Subject: [PATCH] clk: sifive: Fix missing conversion to struct clk_hw

Sifive was not converted to the recent struct clk_hw changes. Add these.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/sifive/sifive-prci.c | 42 +++++++++++++++++---------------
 drivers/clk/sifive/sifive-prci.h | 18 +++++++-------
 2 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index b452bbf8cc..1701a2c5a0 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -185,7 +185,7 @@ static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
  * these functions.
  */
 
-unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
@@ -194,7 +194,7 @@ unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
 	return wrpll_calc_output_rate(&pwd->c, parent_rate);
 }
 
-long sifive_prci_wrpll_round_rate(struct clk *hw,
+long sifive_prci_wrpll_round_rate(struct clk_hw *hw,
 				  unsigned long rate,
 				  unsigned long *parent_rate)
 {
@@ -209,7 +209,7 @@ long sifive_prci_wrpll_round_rate(struct clk *hw,
 	return wrpll_calc_output_rate(&c, *parent_rate);
 }
 
-int sifive_prci_wrpll_set_rate(struct clk *hw,
+int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
 			       unsigned long rate, unsigned long parent_rate)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
@@ -231,7 +231,7 @@ int sifive_prci_wrpll_set_rate(struct clk *hw,
 	return 0;
 }
 
-int sifive_clk_is_enabled(struct clk *hw)
+int sifive_clk_is_enabled(struct clk_hw *hw)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
 	struct __prci_wrpll_data *pwd = pc->pwd;
@@ -246,7 +246,7 @@ int sifive_clk_is_enabled(struct clk *hw)
 		return 0;
 }
 
-int sifive_prci_clock_enable(struct clk *hw)
+int sifive_prci_clock_enable(struct clk_hw *hw)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
 	struct __prci_wrpll_data *pwd = pc->pwd;
@@ -263,7 +263,7 @@ int sifive_prci_clock_enable(struct clk *hw)
 	return 0;
 }
 
-void sifive_prci_clock_disable(struct clk *hw)
+void sifive_prci_clock_disable(struct clk_hw *hw)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
 	struct __prci_wrpll_data *pwd = pc->pwd;
@@ -281,7 +281,7 @@ void sifive_prci_clock_disable(struct clk *hw)
 
 /* TLCLKSEL clock integration */
 
-unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
 					       unsigned long parent_rate)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
@@ -298,7 +298,7 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
 
 /* HFPCLK clock integration */
 
-unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk *hw,
+unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
 						   unsigned long parent_rate)
 {
 	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
@@ -473,6 +473,7 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
 static int __prci_register_clocks(struct device_d *dev, struct __prci_data *pd,
 				  const struct prci_clk_desc *desc)
 {
+	struct clk_init_data init = { };
 	struct __prci_clock *pic;
 	int parent_count, i, r;
 
@@ -485,33 +486,36 @@ static int __prci_register_clocks(struct device_d *dev, struct __prci_data *pd,
 
 	/* Register PLLs */
 	for (i = 0; i < desc->num_clks; ++i) {
+		struct clk *clk;
+
 		pic = &(desc->clks[i]);
 
-		pic->hw.name = pic->name;
-		pic->hw.parent_names = &pic->parent_name;
-		pic->hw.num_parents = 1;
-		pic->hw.ops = pic->ops;
+		init.name = pic->name;
+		init.parent_names = &pic->parent_name;
+		init.num_parents = 1;
+		init.ops = pic->ops;
+		pic->hw.init = &init;
 
 		pic->pd = pd;
 
 		if (pic->pwd)
 			__prci_wrpll_read_cfg0(pd, pic->pwd);
 
-		r = clk_register(&pic->hw);
-		if (r) {
+		clk = clk_register(dev, &pic->hw);
+		if (IS_ERR(clk)) {
 			dev_warn(dev, "Failed to register clock %s: %d\n",
-				 pic->hw.name, r);
-			return r;
+				 clk_hw_get_name(&pic->hw), r);
+			return PTR_ERR(clk);
 		}
 
-		r = clk_register_clkdev(&pic->hw, pic->name, dev_name(dev));
+		r = clk_register_clkdev(clk, pic->name, dev_name(dev));
 		if (r) {
 			dev_warn(dev, "Failed to register clkdev for %s: %d\n",
-				 pic->hw.name, r);
+				 clk_hw_get_name(&pic->hw), r);
 			return r;
 		}
 
-		pd->hw_clks.clks[i] = &pic->hw;
+		pd->hw_clks.clks[i] = clk;
 	}
 
 	pd->hw_clks.clk_num = i;
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index d851553818..e7a04ae790 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -254,7 +254,7 @@ struct __prci_clock {
 	const char *name;
 	const char *parent_name;
 	const struct clk_ops *ops;
-	struct clk hw;
+	struct clk_hw hw;
 	struct __prci_wrpll_data *pwd;
 	struct __prci_data *pd;
 };
@@ -281,18 +281,18 @@ void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
 void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
 
 /* Linux clock framework integration */
-long sifive_prci_wrpll_round_rate(struct clk *hw, unsigned long rate,
+long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long *parent_rate);
-int sifive_prci_wrpll_set_rate(struct clk *hw, unsigned long rate,
+int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate);
-int sifive_clk_is_enabled(struct clk *hw);
-int sifive_prci_clock_enable(struct clk *hw);
-void sifive_prci_clock_disable(struct clk *hw);
-unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
+int sifive_clk_is_enabled(struct clk_hw *hw);
+int sifive_prci_clock_enable(struct clk_hw *hw);
+void sifive_prci_clock_disable(struct clk_hw *hw);
+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
 					    unsigned long parent_rate);
-unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
 					       unsigned long parent_rate);
-unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk *hw,
+unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
 						   unsigned long parent_rate);
 
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
-- 
2.29.2

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-11  8:41     ` Sascha Hauer
@ 2021-06-11  9:19       ` Ahmad Fatoum
  2021-06-11 11:46         ` Sascha Hauer
  0 siblings, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-06-11  9:19 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hello Sascha,

On 11.06.21 10:41, Sascha Hauer wrote:
> On Fri, Jun 11, 2021 at 09:55:36AM +0200, Ahmad Fatoum wrote:
>> Hello Sascha,
>>
>> On 02.06.21 11:54, Sascha Hauer wrote:
>>
>>> In Linux the ops in struct clk_ops take a struct clk_hw * argument
>>
>>> instead of a struct clk * argument as in barebox. With this taking
>>
>>> new clk drivers from Linux requires a lot of mechanical conversions.
>>
>>> Instead of doing this over and over again swallow the pill once and
>>
>>> convert the existing barebox code over to clk_hw.
>>
>>>
>>
>>> The implementation is a little different from Linux. In Linux struct clk
>>
>>> is only known to the core clock code. In barebox struct clk is
>>
>>> publically known and it is embedded into struct clk_hw. This allows
>>
>>> us to still use struct clk members in the clock drivers which we
>>
>>> currently still need, because otherwise this patch would be even
>>
>>> bigger.
>>
>>>
>>
>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>
>> drivers/clk/sifive, which was added recently doesn't have these changes
>> and thus the build fails. To reproduce, without installed RISC-V toolchain, try:
>>
>>    ./test/emulate.pl --runtime=podman sifive_defconfig
> 
> Can't exec "tuxmake": No such file or directory at ./test/emulate.pl line 377.
> 
> Where do I get this from?

pip3 install tuxmake

>> Doing the conversions aren't completely trivial to me, as there are no
>> clkdev clk_hw helpers ported and I still need to figure out how to use them.
>> Given that your caches are still hot, could you take a look?
> 
> Here we go. I added the following to next.

Just tested in QEMU and works fine!
You should still try emulate.pl above though. If it runs through, it will
start a QEMU VM, where dhcp working will tell you that the clock changes
seem ok.

Cheers,
Ahmad

> 
> Sascha
> 
> ---------------------------8<--------------------------------
> 
> From 61da1fea5d3c516d7f2609daebfc19e035a4c485 Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Date: Fri, 11 Jun 2021 10:38:27 +0200
> Subject: [PATCH] clk: sifive: Fix missing conversion to struct clk_hw
> 
> Sifive was not converted to the recent struct clk_hw changes. Add these.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/clk/sifive/sifive-prci.c | 42 +++++++++++++++++---------------
>  drivers/clk/sifive/sifive-prci.h | 18 +++++++-------
>  2 files changed, 32 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
> index b452bbf8cc..1701a2c5a0 100644
> --- a/drivers/clk/sifive/sifive-prci.c
> +++ b/drivers/clk/sifive/sifive-prci.c
> @@ -185,7 +185,7 @@ static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
>   * these functions.
>   */
>  
> -unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
> +unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
>  					    unsigned long parent_rate)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
> @@ -194,7 +194,7 @@ unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
>  	return wrpll_calc_output_rate(&pwd->c, parent_rate);
>  }
>  
> -long sifive_prci_wrpll_round_rate(struct clk *hw,
> +long sifive_prci_wrpll_round_rate(struct clk_hw *hw,
>  				  unsigned long rate,
>  				  unsigned long *parent_rate)
>  {
> @@ -209,7 +209,7 @@ long sifive_prci_wrpll_round_rate(struct clk *hw,
>  	return wrpll_calc_output_rate(&c, *parent_rate);
>  }
>  
> -int sifive_prci_wrpll_set_rate(struct clk *hw,
> +int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
>  			       unsigned long rate, unsigned long parent_rate)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
> @@ -231,7 +231,7 @@ int sifive_prci_wrpll_set_rate(struct clk *hw,
>  	return 0;
>  }
>  
> -int sifive_clk_is_enabled(struct clk *hw)
> +int sifive_clk_is_enabled(struct clk_hw *hw)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
>  	struct __prci_wrpll_data *pwd = pc->pwd;
> @@ -246,7 +246,7 @@ int sifive_clk_is_enabled(struct clk *hw)
>  		return 0;
>  }
>  
> -int sifive_prci_clock_enable(struct clk *hw)
> +int sifive_prci_clock_enable(struct clk_hw *hw)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
>  	struct __prci_wrpll_data *pwd = pc->pwd;
> @@ -263,7 +263,7 @@ int sifive_prci_clock_enable(struct clk *hw)
>  	return 0;
>  }
>  
> -void sifive_prci_clock_disable(struct clk *hw)
> +void sifive_prci_clock_disable(struct clk_hw *hw)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
>  	struct __prci_wrpll_data *pwd = pc->pwd;
> @@ -281,7 +281,7 @@ void sifive_prci_clock_disable(struct clk *hw)
>  
>  /* TLCLKSEL clock integration */
>  
> -unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
> +unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
>  					       unsigned long parent_rate)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
> @@ -298,7 +298,7 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
>  
>  /* HFPCLK clock integration */
>  
> -unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk *hw,
> +unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
>  						   unsigned long parent_rate)
>  {
>  	struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
> @@ -473,6 +473,7 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
>  static int __prci_register_clocks(struct device_d *dev, struct __prci_data *pd,
>  				  const struct prci_clk_desc *desc)
>  {
> +	struct clk_init_data init = { };
>  	struct __prci_clock *pic;
>  	int parent_count, i, r;
>  
> @@ -485,33 +486,36 @@ static int __prci_register_clocks(struct device_d *dev, struct __prci_data *pd,
>  
>  	/* Register PLLs */
>  	for (i = 0; i < desc->num_clks; ++i) {
> +		struct clk *clk;
> +
>  		pic = &(desc->clks[i]);
>  
> -		pic->hw.name = pic->name;
> -		pic->hw.parent_names = &pic->parent_name;
> -		pic->hw.num_parents = 1;
> -		pic->hw.ops = pic->ops;
> +		init.name = pic->name;
> +		init.parent_names = &pic->parent_name;
> +		init.num_parents = 1;
> +		init.ops = pic->ops;
> +		pic->hw.init = &init;
>  
>  		pic->pd = pd;
>  
>  		if (pic->pwd)
>  			__prci_wrpll_read_cfg0(pd, pic->pwd);
>  
> -		r = clk_register(&pic->hw);
> -		if (r) {
> +		clk = clk_register(dev, &pic->hw);
> +		if (IS_ERR(clk)) {
>  			dev_warn(dev, "Failed to register clock %s: %d\n",
> -				 pic->hw.name, r);
> -			return r;
> +				 clk_hw_get_name(&pic->hw), r);
> +			return PTR_ERR(clk);
>  		}
>  
> -		r = clk_register_clkdev(&pic->hw, pic->name, dev_name(dev));
> +		r = clk_register_clkdev(clk, pic->name, dev_name(dev));
>  		if (r) {
>  			dev_warn(dev, "Failed to register clkdev for %s: %d\n",
> -				 pic->hw.name, r);
> +				 clk_hw_get_name(&pic->hw), r);
>  			return r;
>  		}
>  
> -		pd->hw_clks.clks[i] = &pic->hw;
> +		pd->hw_clks.clks[i] = clk;
>  	}
>  
>  	pd->hw_clks.clk_num = i;
> diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
> index d851553818..e7a04ae790 100644
> --- a/drivers/clk/sifive/sifive-prci.h
> +++ b/drivers/clk/sifive/sifive-prci.h
> @@ -254,7 +254,7 @@ struct __prci_clock {
>  	const char *name;
>  	const char *parent_name;
>  	const struct clk_ops *ops;
> -	struct clk hw;
> +	struct clk_hw hw;
>  	struct __prci_wrpll_data *pwd;
>  	struct __prci_data *pd;
>  };
> @@ -281,18 +281,18 @@ void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
>  void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
>  
>  /* Linux clock framework integration */
> -long sifive_prci_wrpll_round_rate(struct clk *hw, unsigned long rate,
> +long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
>  				  unsigned long *parent_rate);
> -int sifive_prci_wrpll_set_rate(struct clk *hw, unsigned long rate,
> +int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
>  			       unsigned long parent_rate);
> -int sifive_clk_is_enabled(struct clk *hw);
> -int sifive_prci_clock_enable(struct clk *hw);
> -void sifive_prci_clock_disable(struct clk *hw);
> -unsigned long sifive_prci_wrpll_recalc_rate(struct clk *hw,
> +int sifive_clk_is_enabled(struct clk_hw *hw);
> +int sifive_prci_clock_enable(struct clk_hw *hw);
> +void sifive_prci_clock_disable(struct clk_hw *hw);
> +unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
>  					    unsigned long parent_rate);
> -unsigned long sifive_prci_tlclksel_recalc_rate(struct clk *hw,
> +unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
>  					       unsigned long parent_rate);
> -unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk *hw,
> +unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
>  						   unsigned long parent_rate);
>  
>  #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-11  9:19       ` Ahmad Fatoum
@ 2021-06-11 11:46         ` Sascha Hauer
  2021-06-11 12:14           ` Ahmad Fatoum
  0 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-06-11 11:46 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On Fri, Jun 11, 2021 at 11:19:12AM +0200, Ahmad Fatoum wrote:
> Hello Sascha,
> 
> On 11.06.21 10:41, Sascha Hauer wrote:
> > On Fri, Jun 11, 2021 at 09:55:36AM +0200, Ahmad Fatoum wrote:
> >> Hello Sascha,
> >>
> >> On 02.06.21 11:54, Sascha Hauer wrote:
> >>
> >>> In Linux the ops in struct clk_ops take a struct clk_hw * argument
> >>
> >>> instead of a struct clk * argument as in barebox. With this taking
> >>
> >>> new clk drivers from Linux requires a lot of mechanical conversions.
> >>
> >>> Instead of doing this over and over again swallow the pill once and
> >>
> >>> convert the existing barebox code over to clk_hw.
> >>
> >>>
> >>
> >>> The implementation is a little different from Linux. In Linux struct clk
> >>
> >>> is only known to the core clock code. In barebox struct clk is
> >>
> >>> publically known and it is embedded into struct clk_hw. This allows
> >>
> >>> us to still use struct clk members in the clock drivers which we
> >>
> >>> currently still need, because otherwise this patch would be even
> >>
> >>> bigger.
> >>
> >>>
> >>
> >>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> >>
> >> drivers/clk/sifive, which was added recently doesn't have these changes
> >> and thus the build fails. To reproduce, without installed RISC-V toolchain, try:
> >>
> >>    ./test/emulate.pl --runtime=podman sifive_defconfig
> > 
> > Can't exec "tuxmake": No such file or directory at ./test/emulate.pl line 377.
> > 
> > Where do I get this from?
> 
> pip3 install tuxmake

Now it complains about missing podman... /me waits for Debian 11.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 04/24] clk: introduce struct clk_hw
  2021-06-11 11:46         ` Sascha Hauer
@ 2021-06-11 12:14           ` Ahmad Fatoum
  0 siblings, 0 replies; 34+ messages in thread
From: Ahmad Fatoum @ 2021-06-11 12:14 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

Hi,

On 11.06.21 13:46, Sascha Hauer wrote:
>>> Where do I get this from?
>>
>> pip3 install tuxmake
> 
> Now it complains about missing podman... /me waits for Debian 11.

Alternatively dorp the --runtime=podman and install locally a RISC-V toolchain:
apt install gcc-riscv64-linux-gnu

> 
> Sascha
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

end of thread, other threads:[~2021-06-11 12:15 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02  9:54 [PATCH v2 00/24] clk updates Sascha Hauer
2021-06-02  9:54 ` [PATCH 01/24] clk: clk-mux: Fix handling of CLK_MUX_HIWORD_MASK Sascha Hauer
2021-06-02 15:18   ` Ahmad Fatoum
2021-06-02  9:54 ` [PATCH 02/24] clk: introduce clk init op Sascha Hauer
2021-06-02  9:54 ` [PATCH 03/24] clk: rename clk_register() to bclk_register() Sascha Hauer
2021-06-02  9:54 ` [PATCH 04/24] clk: introduce struct clk_hw Sascha Hauer
2021-06-11  7:55   ` Ahmad Fatoum
2021-06-11  8:41     ` Sascha Hauer
2021-06-11  9:19       ` Ahmad Fatoum
2021-06-11 11:46         ` Sascha Hauer
2021-06-11 12:14           ` Ahmad Fatoum
2021-06-02  9:54 ` [PATCH 05/24] clk: introduce clk_register() Sascha Hauer
2021-06-02  9:54 ` [PATCH 06/24] clk: divider: Make clk_divider_ops const Sascha Hauer
2021-06-02  9:54 ` [PATCH 07/24] clk: divider: Add ro ops Sascha Hauer
2021-06-02  9:54 ` [PATCH 08/24] clk: divider: Make clk_mux_ops const Sascha Hauer
2021-06-02  9:54 ` [PATCH 09/24] clk: mux: Add ro ops Sascha Hauer
2021-06-02  9:54 ` [PATCH 10/24] clk: move fixed_factor to include/linux/clk.h Sascha Hauer
2021-06-02  9:54 ` [PATCH 11/24] Add rational_best_approximation() Sascha Hauer
2021-06-02 18:25   ` Trent Piepho
2021-06-07 11:22     ` Sascha Hauer
2021-06-02  9:54 ` [PATCH 12/24] clk: Update fractional divider from Linux Sascha Hauer
2021-06-02  9:54 ` [PATCH 13/24] clk: Add lock to different clock types Sascha Hauer
2021-06-02  9:54 ` [PATCH 14/24] clk: Add Linux functions to register a divider Sascha Hauer
2021-06-02  9:54 ` [PATCH 15/24] clk: Add Linux functions to register a fixed factor clock Sascha Hauer
2021-06-02  9:54 ` [PATCH 16/24] clk: Add Linux functions to register a gate Sascha Hauer
2021-06-02  9:55 ` [PATCH 17/24] clk: Add Linux functions to register a mux Sascha Hauer
2021-06-02  9:55 ` [PATCH 18/24] clk: Add CLK_GET_RATE_NOCACHE Sascha Hauer
2021-06-02  9:55 ` [PATCH 19/24] clk: Rename CLK_GATE_INVERTED to CLK_GATE_SET_TO_DISABLE Sascha Hauer
2021-06-02  9:55 ` [PATCH 20/24] clk: implement CLK_SET_RATE_UNGATE Sascha Hauer
2021-06-02  9:55 ` [PATCH 21/24] clk: implement set/get phase Sascha Hauer
2021-06-02  9:55 ` [PATCH 22/24] regmap: Add regmap_read_poll_timeout Sascha Hauer
2021-06-02  9:55 ` [PATCH 23/24] clk: rockchip: Update to current Linux Sascha Hauer
2021-06-02  9:55 ` [PATCH 24/24] clk: Rockchip: Add rk3568 clk support Sascha Hauer
2021-06-09  9:18   ` Ahmad Fatoum

mail archive of the barebox mailing list

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://lore.barebox.org/barebox/0 barebox/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 barebox barebox/ https://lore.barebox.org/barebox \
		barebox@lists.infradead.org barebox@lists.infradead.org
	public-inbox-index barebox

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git