linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng
@ 2016-11-08 17:23 Maxime Ripard
  2016-11-08 17:23 ` [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support Maxime Ripard
                   ` (9 more replies)
  0 siblings, 10 replies; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Hi,

This is yet another serie bringing more SoCs into the sunxi-ng world.

This is pretty common stuff. Dealing with more corner cases, and adding the
drivers for the SoCs. The A10 and A20 should be pretty close, and pretty
easy to support after that.

Let me know what you think,
Maxime

Maxime Ripard (10):
  clk: sunxi-ng: multiplier: Add fractionnal support
  clk: sunxi-ng: nkm: Deal with fixed post dividers
  clk: sunxi-ng: Implement multiplier offsets
  clk: sunxi-ng: Add clocks and resets indices for sun5i
  clk: sunxi-ng: Implement multiplier maximum
  clk: sunxi-ng: Add A10s CCU driver
  clk: sunxi-ng: Add A13 CCU driver
  clk: sunxi-ng: Add GR8 driver
  ARM: sun5i: Convert to CCU
  ARM: gr8: Convert to CCU

 arch/arm/boot/dts/ntc-gr8.dtsi        | 518 ++-----------------
 arch/arm/boot/dts/sun5i-a10s.dtsi     |  94 +---
 arch/arm/boot/dts/sun5i-a13.dtsi      | 140 +-----
 arch/arm/boot/dts/sun5i-r8.dtsi       |  10 +-
 arch/arm/boot/dts/sun5i.dtsi          | 368 +------------
 drivers/clk/sunxi-ng/Kconfig          |  30 +-
 drivers/clk/sunxi-ng/Makefile         |   3 +-
 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c | 755 +++++++++++++++++++++++++++-
 drivers/clk/sunxi-ng/ccu-sun5i-a13.c  | 681 ++++++++++++++++++++++++-
 drivers/clk/sunxi-ng/ccu-sun5i-gr8.c  | 684 ++++++++++++++++++++++++-
 drivers/clk/sunxi-ng/ccu-sun5i.h      | 129 +++++-
 drivers/clk/sunxi-ng/ccu_div.h        |  10 +-
 drivers/clk/sunxi-ng/ccu_mp.c         |  10 +-
 drivers/clk/sunxi-ng/ccu_mult.c       |  12 +-
 drivers/clk/sunxi-ng/ccu_mult.h       |  24 +-
 drivers/clk/sunxi-ng/ccu_nk.c         |  14 +-
 drivers/clk/sunxi-ng/ccu_nkm.c        |  33 +-
 drivers/clk/sunxi-ng/ccu_nkm.h        |   2 +-
 drivers/clk/sunxi-ng/ccu_nkmp.c       |  17 +-
 drivers/clk/sunxi-ng/ccu_nm.c         |  13 +-
 include/dt-bindings/clock/sun5i-ccu.h | 126 +++++-
 include/dt-bindings/reset/sun5i-ccu.h |  32 +-
 22 files changed, 2690 insertions(+), 1015 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a13.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-gr8.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i.h
 create mode 100644 include/dt-bindings/clock/sun5i-ccu.h
 create mode 100644 include/dt-bindings/reset/sun5i-ccu.h

base-commit: bc5952be2d424b75ed11ff599b70bc9604e98d42
-- 
git-series 0.8.11

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

* [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-10  6:18   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers Maxime Ripard
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu_mult.c | 8 ++++++++
 drivers/clk/sunxi-ng/ccu_mult.h | 2 ++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
index 678b6cb49f01..826302464650 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.c
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -75,6 +75,9 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
 	unsigned long val;
 	u32 reg;
 
+	if (ccu_frac_helper_is_enabled(&cm->common, &cm->frac))
+		return ccu_frac_helper_read_rate(&cm->common, &cm->frac);
+
 	reg = readl(cm->common.base + cm->common.reg);
 	val = reg >> cm->mult.shift;
 	val &= (1 << cm->mult.width) - 1;
@@ -102,6 +105,11 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long flags;
 	u32 reg;
 
+	if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
+		return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
+	else
+		ccu_frac_helper_disable(&cm->common, &cm->frac);
+
 	ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
 						&parent_rate);
 
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index c1a2134bdc71..bd2e38b5a32a 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -2,6 +2,7 @@
 #define _CCU_MULT_H_
 
 #include "ccu_common.h"
+#include "ccu_frac.h"
 #include "ccu_mux.h"
 
 struct ccu_mult_internal {
@@ -23,6 +24,7 @@ struct ccu_mult_internal {
 struct ccu_mult {
 	u32			enable;
 
+	struct ccu_frac_internal	frac;
 	struct ccu_mult_internal	mult;
 	struct ccu_mux_internal	mux;
 	struct ccu_common	common;
-- 
git-series 0.8.11

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

* [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
  2016-11-08 17:23 ` [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  3:48   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets Maxime Ripard
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu_nkm.c | 17 ++++++++++++++---
 drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 9b840a47a94d..fd3c6a9d987c 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
 					unsigned long parent_rate)
 {
 	struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
-	unsigned long n, m, k;
+	unsigned long rate, n, m, k;
 	u32 reg;
 
 	reg = readl(nkm->common.base + nkm->common.reg);
@@ -89,7 +89,11 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
 	m = reg >> nkm->m.shift;
 	m &= (1 << nkm->m.width) - 1;
 
-	return parent_rate * (n + 1) * (k + 1) / (m + 1);
+	rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
+	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+		rate /= nkm->fixed_post_div;
+
+	return rate;
 }
 
 static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
@@ -100,6 +104,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
 	struct ccu_nkm *nkm = data;
 	struct _ccu_nkm _nkm;
 
+	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+		rate *= nkm->fixed_post_div;
+
 	_nkm.min_n = nkm->n.min;
 	_nkm.max_n = 1 << nkm->n.width;
 	_nkm.min_k = nkm->k.min;
@@ -109,7 +116,11 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
 
 	ccu_nkm_find_best(parent_rate, rate, &_nkm);
 
-	return parent_rate * _nkm.n * _nkm.k / _nkm.m;
+	rate = parent_rate * _nkm.n * _nkm.k / _nkm.m;
+	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+		rate = rate / nkm->fixed_post_div;
+
+	return rate;
 }
 
 static int ccu_nkm_determine_rate(struct clk_hw *hw,
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index 34580894f4d1..0f1dbca25719 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -32,6 +32,8 @@ struct ccu_nkm {
 	struct ccu_mult_internal	n;
 	struct ccu_mult_internal	k;
 	struct ccu_div_internal		m;
+
+	unsigned int		fixed_post_div;
 	struct ccu_mux_internal	mux;
 
 	struct ccu_common	common;
-- 
git-series 0.8.11

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

* [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
  2016-11-08 17:23 ` [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support Maxime Ripard
  2016-11-08 17:23 ` [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  4:18   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i Maxime Ripard
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

The multipliers we've seen so far all had an offset of one. However, on the
earlier Allwinner SoCs, the multipliers could have no offset at all.

Implement an additional field for the multipliers to specify that offset.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu_div.h  | 10 +++++++++-
 drivers/clk/sunxi-ng/ccu_mp.c   | 10 +++++++---
 drivers/clk/sunxi-ng/ccu_mult.c |  4 ++--
 drivers/clk/sunxi-ng/ccu_mult.h | 20 ++++++++++++++------
 drivers/clk/sunxi-ng/ccu_nk.c   | 14 ++++++++++----
 drivers/clk/sunxi-ng/ccu_nkm.c  | 18 +++++++++++++-----
 drivers/clk/sunxi-ng/ccu_nkmp.c | 17 +++++++++++++----
 drivers/clk/sunxi-ng/ccu_nm.c   | 13 ++++++++++---
 8 files changed, 78 insertions(+), 28 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 06540f7cf41c..08d074451204 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -41,6 +41,7 @@ struct ccu_div_internal {
 	u8			width;
 
 	u32			max;
+	u32			offset;
 
 	u32			flags;
 
@@ -58,20 +59,27 @@ struct ccu_div_internal {
 #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)			\
 	_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
 
-#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
+#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
 	{								\
 		.shift	= _shift,					\
 		.width	= _width,					\
 		.flags	= _flags,					\
 		.max	= _max,						\
+		.offset	= _off,						\
 	}
 
+#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)		\
+	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
+
 #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)			\
 	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
 
 #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)			\
 	_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
 
+#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)			\
+	_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
+
 #define _SUNXI_CCU_DIV(_shift, _width)					\
 	_SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
 
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index ebb1b31568a5..22c2ca7a2a22 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -89,11 +89,14 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
 
 	m = reg >> cmp->m.shift;
 	m &= (1 << cmp->m.width) - 1;
+	m += cmp->m.offset;
+	if (!m)
+		m++;
 
 	p = reg >> cmp->p.shift;
 	p &= (1 << cmp->p.width) - 1;
 
-	return (parent_rate >> p) / (m + 1);
+	return (parent_rate >> p) / m;
 }
 
 static int ccu_mp_determine_rate(struct clk_hw *hw,
@@ -124,9 +127,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg = readl(cmp->common.base + cmp->common.reg);
 	reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
 	reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
+	reg |= (m - cmp->m.offset) << cmp->m.shift;
+	reg |= ilog2(p) << cmp->p.shift;
 
-	writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
-	       cmp->common.base + cmp->common.reg);
+	writel(reg, cmp->common.base + cmp->common.reg);
 
 	spin_unlock_irqrestore(cmp->common.lock, flags);
 
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
index 826302464650..bf5e11c803f9 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.c
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -85,7 +85,7 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
 	ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
 						&parent_rate);
 
-	return parent_rate * (val + 1);
+	return parent_rate * (val + cm->mult.offset);
 }
 
 static int ccu_mult_determine_rate(struct clk_hw *hw,
@@ -122,7 +122,7 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg = readl(cm->common.base + cm->common.reg);
 	reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
 
-	writel(reg | ((_cm.mult - 1) << cm->mult.shift),
+	writel(reg | ((_cm.mult - cm->mult.offset) << cm->mult.shift),
 	       cm->common.base + cm->common.reg);
 
 	spin_unlock_irqrestore(cm->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index bd2e38b5a32a..84839641dfdf 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -6,20 +6,28 @@
 #include "ccu_mux.h"
 
 struct ccu_mult_internal {
+	u8	offset;
 	u8	shift;
 	u8	width;
 	u8	min;
 };
 
-#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)	\
-	{						\
-		.shift	= _shift,			\
-		.width	= _width,			\
-		.min	= _min,				\
+#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min)	\
+	{								\
+		.min	= _min,						\
+		.offset	= _offset,					\
+		.shift	= _shift,					\
+		.width	= _width,					\
 	}
 
+#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)	\
+	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
+
+#define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset)	\
+	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
+
 #define _SUNXI_CCU_MULT(_shift, _width)		\
-	_SUNXI_CCU_MULT_MIN(_shift, _width, 1)
+	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
 
 struct ccu_mult {
 	u32			enable;
diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
index eaf0fdf78d2b..90117d3ead8c 100644
--- a/drivers/clk/sunxi-ng/ccu_nk.c
+++ b/drivers/clk/sunxi-ng/ccu_nk.c
@@ -76,12 +76,17 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw,
 
 	n = reg >> nk->n.shift;
 	n &= (1 << nk->n.width) - 1;
+	n += nk->n.offset;
+	if (!n)
+		n++;
 
 	k = reg >> nk->k.shift;
 	k &= (1 << nk->k.width) - 1;
+	k += nk->k.offset;
+	if (!k)
+		k++;
 
-	rate = parent_rate * (n + 1) * (k + 1);
-
+	rate = parent_rate * n * k;
 	if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nk->fixed_post_div;
 
@@ -135,8 +140,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift);
 	reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift);
 
-	writel(reg | ((_nk.k - 1) << nk->k.shift) | ((_nk.n - 1) << nk->n.shift),
-	       nk->common.base + nk->common.reg);
+	reg |= (_nk.k - nk->k.offset) << nk->k.shift;
+	reg |= (_nk.n - nk->n.offset) << nk->n.shift;
+	writel(reg, nk->common.base + nk->common.reg);
 
 	spin_unlock_irqrestore(nk->common.lock, flags);
 
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index fd3c6a9d987c..e0b4c914d7ac 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -82,14 +82,23 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
 
 	n = reg >> nkm->n.shift;
 	n &= (1 << nkm->n.width) - 1;
+	n += nkm->n.offset;
+	if (!n)
+		n++;
 
 	k = reg >> nkm->k.shift;
 	k &= (1 << nkm->k.width) - 1;
+	k += nkm->k.offset;
+	if (!k)
+		k++;
 
 	m = reg >> nkm->m.shift;
 	m &= (1 << nkm->m.width) - 1;
+	m += nkm->m.offset;
+	if (!m)
+		m++;
 
-	rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
+	rate = parent_rate * n  * k / m;
 	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nkm->fixed_post_div;
 
@@ -156,10 +165,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
 	reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);
 
-	reg |= (_nkm.n - 1) << nkm->n.shift;
-	reg |= (_nkm.k - 1) << nkm->k.shift;
-	reg |= (_nkm.m - 1) << nkm->m.shift;
-
+	reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
+	reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
+	reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
 	writel(reg, nkm->common.base + nkm->common.reg);
 
 	spin_unlock_irqrestore(nkm->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index 684c42da3ebb..da2bba02b845 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -88,17 +88,26 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
 
 	n = reg >> nkmp->n.shift;
 	n &= (1 << nkmp->n.width) - 1;
+	n += nkmp->n.offset;
+	if (!n)
+		n++;
 
 	k = reg >> nkmp->k.shift;
 	k &= (1 << nkmp->k.width) - 1;
+	k += nkmp->k.offset;
+	if (!k)
+		k++;
 
 	m = reg >> nkmp->m.shift;
 	m &= (1 << nkmp->m.width) - 1;
+	m += nkmp->m.offset;
+	if (!m)
+		m++;
 
 	p = reg >> nkmp->p.shift;
 	p &= (1 << nkmp->p.width) - 1;
 
-	return (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
+	return parent_rate * n * k >> p / m;
 }
 
 static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -148,9 +157,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
 	reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
 
-	reg |= (_nkmp.n - 1) << nkmp->n.shift;
-	reg |= (_nkmp.k - 1) << nkmp->k.shift;
-	reg |= (_nkmp.m - 1) << nkmp->m.shift;
+	reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
+	reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
+	reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
 	reg |= ilog2(_nkmp.p) << nkmp->p.shift;
 
 	writel(reg, nkmp->common.base + nkmp->common.reg);
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index c9f3b6c982f0..158d74e0215f 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -80,11 +80,17 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
 
 	n = reg >> nm->n.shift;
 	n &= (1 << nm->n.width) - 1;
+	n += nm->n.offset;
+	if (!n)
+		n++;
 
 	m = reg >> nm->m.shift;
 	m &= (1 << nm->m.width) - 1;
+	m += nm->m.offset;
+	if (!m)
+		m++;
 
-	return parent_rate * (n + 1) / (m + 1);
+	return parent_rate * n / m;
 }
 
 static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -129,8 +135,9 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
 	reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
 	reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
 
-	writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift),
-	       nm->common.base + nm->common.reg);
+	reg |= (_nm.n - nm->n.offset) << nm->n.shift;
+	reg |= (_nm.m - nm->m.offset) << nm->m.shift;
+	writel(reg, nm->common.base + nm->common.reg);
 
 	spin_unlock_irqrestore(nm->common.lock, flags);
 
-- 
git-series 0.8.11

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

* [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (2 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  4:29   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum Maxime Ripard
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

The SoCs part of the sun5i family share the DTs, so we need consistant
indices in order to still share the DTs.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 include/dt-bindings/clock/sun5i-ccu.h | 126 +++++++++++++++++++++++++++-
 include/dt-bindings/reset/sun5i-ccu.h |  32 +++++++-
 2 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 include/dt-bindings/clock/sun5i-ccu.h
 create mode 100644 include/dt-bindings/reset/sun5i-ccu.h

diff --git a/include/dt-bindings/clock/sun5i-ccu.h b/include/dt-bindings/clock/sun5i-ccu.h
new file mode 100644
index 000000000000..32735b2cf29c
--- /dev/null
+++ b/include/dt-bindings/clock/sun5i-ccu.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2016 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN5I_H_
+#define _CCU_SUN5I_H_
+
+#define CLK_HOSC		1
+#define CLK_OSC3M		2
+#define CLK_PLL_CORE		3
+#define CLK_PLL_AUDIO_BASE	4
+#define CLK_PLL_AUDIO		5
+#define CLK_PLL_AUDIO_2X	6
+#define CLK_PLL_AUDIO_4X	7
+#define CLK_PLL_AUDIO_8X	8
+#define CLK_PLL_VIDEO0		9
+#define CLK_PLL_VIDEO0_2X	10
+#define CLK_PLL_VE		11
+#define CLK_PLL_DDR_BASE	12
+#define CLK_PLL_DDR		13
+#define CLK_PLL_DDR_OTHER	14
+#define CLK_PLL_PERIPH		15
+#define CLK_PLL_VIDEO1		16
+#define CLK_PLL_VIDEO1_2X	17
+#define CLK_OSC24M		18
+#define CLK_CPU			19
+#define CLK_AXI			20
+#define CLK_AHB			21
+#define CLK_APB0		22
+#define CLK_APB1		23
+#define CLK_DRAM_AXI		24
+#define CLK_AHB_OTG		25
+#define CLK_AHB_EHCI		26
+#define CLK_AHB_OHCI		27
+#define CLK_AHB_SS		28
+#define CLK_AHB_DMA		29
+#define CLK_AHB_BIST		30
+#define CLK_AHB_MMC0		31
+#define CLK_AHB_MMC1		32
+#define CLK_AHB_MMC2		33
+#define CLK_AHB_NAND		34
+#define CLK_AHB_SDRAM		35
+#define CLK_AHB_EMAC		36
+#define CLK_AHB_TS		37
+#define CLK_AHB_SPI0		38
+#define CLK_AHB_SPI1		39
+#define CLK_AHB_SPI2		40
+#define CLK_AHB_GPS		41
+#define CLK_AHB_HSTIMER		42
+#define CLK_AHB_VE		43
+#define CLK_AHB_TVE		44
+#define CLK_AHB_LCD		45
+#define CLK_AHB_CSI		46
+#define CLK_AHB_HDMI		47
+#define CLK_AHB_DE_BE		48
+#define CLK_AHB_DE_FE		49
+#define CLK_AHB_IEP		50
+#define CLK_AHB_GPU		51
+#define CLK_APB0_CODEC		52
+#define CLK_APB0_SPDIF		53
+#define CLK_APB0_I2S		54
+#define CLK_APB0_PIO		55
+#define CLK_APB0_IR		56
+#define CLK_APB0_KEYPAD		57
+#define CLK_APB1_I2C0		58
+#define CLK_APB1_I2C1		59
+#define CLK_APB1_I2C2		60
+#define CLK_APB1_UART0		61
+#define CLK_APB1_UART1		62
+#define CLK_APB1_UART2		63
+#define CLK_APB1_UART3		64
+#define CLK_NAND		65
+#define CLK_MMC0		66
+#define CLK_MMC1		67
+#define CLK_MMC2		68
+#define CLK_TS			69
+#define CLK_SS			70
+#define CLK_CE			71
+#define CLK_SPI0		72
+#define CLK_SPI1		73
+#define CLK_SPI2		74
+#define CLK_IR			75
+#define CLK_I2S			76
+#define CLK_SPDIF		77
+#define CLK_KEYPAD		78
+#define CLK_USB_OHCI		79
+#define CLK_USB_PHY0		80
+#define CLK_USB_PHY1		81
+#define CLK_GPS			82
+#define CLK_DRAM_VE		83
+#define CLK_DRAM_CSI		84
+#define CLK_DRAM_TS		85
+#define CLK_DRAM_TVE		86
+#define CLK_DRAM_DE_FE		87
+#define CLK_DRAM_DE_BE		88
+#define CLK_DRAM_ACE		89
+#define CLK_DRAM_IEP		90
+#define CLK_DE_BE		91
+#define CLK_DE_FE		92
+#define CLK_TCON_CH0		93
+#define CLK_TCON_CH1_SCLK	94
+#define CLK_TCON_CH1		95
+#define CLK_CSI			96
+#define CLK_VE			97
+#define CLK_CODEC		98
+#define CLK_AVS			99
+#define CLK_HDMI		100
+#define CLK_GPU			101
+#define CLK_MBUS		102
+#define CLK_IEP			103
+
+#define CLK_NUMBER		(CLK_IEP + 1)
+
+#endif /* _CCU_SUN5I_H_ */
diff --git a/include/dt-bindings/reset/sun5i-ccu.h b/include/dt-bindings/reset/sun5i-ccu.h
new file mode 100644
index 000000000000..c2b9726b5026
--- /dev/null
+++ b/include/dt-bindings/reset/sun5i-ccu.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _RST_SUN5I_H_
+#define _RST_SUN5I_H_
+
+#define RST_USB_PHY0	0
+#define RST_USB_PHY1	1
+#define RST_GPS		2
+#define RST_DE_BE	3
+#define RST_DE_FE	4
+#define RST_TVE		5
+#define RST_LCD		6
+#define RST_CSI		7
+#define RST_VE		8
+#define RST_GPU		9
+#define RST_IEP		10
+
+#endif /* _RST_SUN5I_H_ */
-- 
git-series 0.8.11

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

* [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (3 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  4:30   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver Maxime Ripard
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu_mult.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index 84839641dfdf..524acddfcb2e 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -10,24 +10,26 @@ struct ccu_mult_internal {
 	u8	shift;
 	u8	width;
 	u8	min;
+	u8	max;
 };
 
-#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min)	\
+#define _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, _min, _max) \
 	{								\
 		.min	= _min,						\
+		.max	= _max,						\
 		.offset	= _offset,					\
 		.shift	= _shift,					\
 		.width	= _width,					\
 	}
 
 #define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)	\
-	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
+	_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, _min, 0)
 
 #define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset)	\
-	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
+	_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, 1, 0)
 
 #define _SUNXI_CCU_MULT(_shift, _width)		\
-	_SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
+	_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, 1, 0)
 
 struct ccu_mult {
 	u32			enable;
-- 
git-series 0.8.11

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

* [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (4 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  9:34   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 7/10] clk: sunxi-ng: Add A13 " Maxime Ripard
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/Kconfig          |  10 +-
 drivers/clk/sunxi-ng/Makefile         |   1 +-
 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c | 755 +++++++++++++++++++++++++++-
 drivers/clk/sunxi-ng/ccu-sun5i.h      | 129 +++++-
 4 files changed, 895 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8454c6e3dd65..e2becd36a1f9 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -64,6 +64,16 @@ config SUN50I_A64_CCU
 	select SUNXI_CCU_PHASE
 	default ARM64 && ARCH_SUNXI
 
+config SUN5I_A10S_CCU
+	bool "Support for the Allwinner A10s CCM"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_NK
+	select SUNXI_CCU_NKM
+	select SUNXI_CCU_NM
+	select SUNXI_CCU_MP
+	select SUNXI_CCU_PHASE
+	default MACH_SUN5I
+
 config SUN6I_A31_CCU
 	bool "Support for the Allwinner A31/A31s CCU"
 	select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 24fbc6e5deb8..79e9a166dc83 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SUNXI_CCU_MP)	+= ccu_mp.o
 
 # SoC support
 obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
+obj-$(CONFIG_SUN5I_A10S_CCU)	+= ccu-sun5i-a10s.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
new file mode 100644
index 000000000000..94d9a5cbf60b
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2016 Maxime Ripard. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun5i.h"
+
+static struct ccu_nkmp pll_core_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x000,
+		.hw.init	= CLK_HW_INIT("pll-core",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we just
+ * hardcode it to match with the clock names
+ */
+#define SUN5I_PLL_AUDIO_REG	0x008
+
+static struct ccu_nm pll_audio_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
+	.m		= _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+	.common		= {
+		.reg		= 0x008,
+		.hw.init	= CLK_HW_INIT("pll-audio-base",
+					      "hosc",
+					      &ccu_nm_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video0_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+					  270000000, 297000000),
+	.common		= {
+		.reg		= 0x010,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video0",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static struct ccu_nkmp pll_ve_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x018,
+		.hw.init	= CLK_HW_INIT("pll-ve",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_ddr_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-base",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
+
+static struct ccu_div pll_ddr_other_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
+					      &ccu_div_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_periph_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.fixed_post_div	= 2,
+	.common		= {
+		.reg		= 0x028,
+		.features	= CCU_FEATURE_FIXED_POSTDIV,
+		.hw.init	= CLK_HW_INIT("pll-periph",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video1_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+				  270000000, 297000000),
+	.common		= {
+		.reg		= 0x030,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video1",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_GATE(hosc_clk,	"hosc",	"osc24M", 0x050, BIT(0), 0);
+
+#define SUN5I_AHB_REG	0x054
+static const char * const cpu_parents[] = { "osc32k", "hosc",
+					    "pll-core" , "pll-periph" };
+static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
+	{ .index = 3, .div = 3, },
+};
+static struct ccu_mux cpu_clk = {
+	.mux		= {
+		.shift		= 16,
+		.width		= 2,
+		.fixed_predivs	= cpu_predivs,
+		.n_predivs	= ARRAY_SIZE(cpu_predivs),
+	},
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("cpu",
+						      cpu_parents,
+						      &ccu_mux_ops,
+						      CLK_IS_CRITICAL),
+	}
+};
+
+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
+
+static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
+static struct ccu_div ahb_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+	.mux		= _SUNXI_CCU_MUX(6, 2),
+
+	.common		= {
+		.reg		= 0x054,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb",
+						      ahb_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static struct clk_div_table apb0_div_table[] = {
+	{ .val = 0, .div = 2 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ /* Sentinel */ },
+};
+static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
+			   0x054, 8, 2, apb0_div_table, 0);
+
+static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(axi_dram_clk,	"axi-dram",	"axi",
+		      0x05c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(ahb_otg_clk,	"ahb-otg",	"ahb",
+		      0x060, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_ehci_clk,	"ahb-ehci",	"ahb",
+		      0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(ahb_ohci_clk,	"ahb-ohci",	"ahb",
+		      0x060, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_ss_clk,	"ahb-ss",	"ahb",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(ahb_dma_clk,	"ahb-dma",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_bist_clk,	"ahb-bist",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_mmc0_clk,	"ahb-mmc0",	"ahb",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_mmc1_clk,	"ahb-mmc1",	"ahb",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(ahb_mmc2_clk,	"ahb-mmc2",	"ahb",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(ahb_nand_clk,	"ahb-nand",	"ahb",
+		      0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(ahb_sdram_clk,	"ahb-sdram",	"ahb",
+		      0x060, BIT(14), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE(ahb_emac_clk,	"ahb-emac",	"ahb",
+		      0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(ahb_ts_clk,	"ahb-ts",	"ahb",
+		      0x060, BIT(18), 0);
+static SUNXI_CCU_GATE(ahb_spi0_clk,	"ahb-spi0",	"ahb",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(ahb_spi1_clk,	"ahb-spi1",	"ahb",
+		      0x060, BIT(21), 0);
+static SUNXI_CCU_GATE(ahb_spi2_clk,	"ahb-spi2",	"ahb",
+		      0x060, BIT(22), 0);
+static SUNXI_CCU_GATE(ahb_gps_clk,	"ahb-gps",	"ahb",
+		      0x060, BIT(26), 0);
+static SUNXI_CCU_GATE(ahb_hstimer_clk,	"ahb-hstimer",	"ahb",
+		      0x060, BIT(28), 0);
+
+static SUNXI_CCU_GATE(ahb_ve_clk,	"ahb-ve",	"ahb",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_tve_clk,	"ahb-tve",	"ahb",
+		      0x064, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_lcd_clk,	"ahb-lcd",	"ahb",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(ahb_csi_clk,	"ahb-csi",	"ahb",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_hdmi_clk,	"ahb-hdmi",	"ahb",
+		      0x064, BIT(11), 0);
+static SUNXI_CCU_GATE(ahb_de_be_clk,	"ahb-de-be",	"ahb",
+		      0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(ahb_de_fe_clk,	"ahb-de-fe",	"ahb",
+		      0x064, BIT(14), 0);
+static SUNXI_CCU_GATE(ahb_iep_clk,	"ahb-iep",	"ahb",
+		      0x064, BIT(19), 0);
+static SUNXI_CCU_GATE(ahb_gpu_clk,	"ahb-gpu",	"ahb",
+		      0x064, BIT(20), 0);
+
+static SUNXI_CCU_GATE(apb0_codec_clk,	"apb0-codec",	"apb0",
+		      0x068, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_i2s_clk,	"apb0-i2s",	"apb0",
+		      0x068, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
+		      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
+		      0x068, BIT(6), 0);
+static SUNXI_CCU_GATE(apb0_keypad_clk,	"apb0-keypad",	"apb0",
+		      0x068, BIT(10), 0);
+
+static SUNXI_CCU_GATE(apb1_i2c0_clk,	"apb1-i2c0",	"apb1",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(apb1_i2c1_clk,	"apb1-i2c1",	"apb1",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(apb1_i2c2_clk,	"apb1-i2c2",	"apb1",
+		      0x06c, BIT(2), 0);
+static SUNXI_CCU_GATE(apb1_uart0_clk,	"apb1-uart0",	"apb1",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(apb1_uart1_clk,	"apb1-uart1",	"apb1",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(apb1_uart2_clk,	"apb1-uart2",	"apb1",
+		      0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(apb1_uart3_clk,	"apb1-uart3",	"apb1",
+		      0x06c, BIT(19), 0);
+
+static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
+						     "pll-ddr-other" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
+					    "pll-audio-2x", "pll-audio" };
+static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
+			       0x0b8, 16, 2, BIT(31), 0);
+
+static const char * const keypad_parents[] = { "hosc", "losc"};
+static const u8 keypad_table[] = { 0, 2 };
+static struct ccu_mp keypad_clk = {
+	.enable		= BIT(31),
+	.m		= _SUNXI_CCU_DIV(8, 5),
+	.p		= _SUNXI_CCU_DIV(20, 2),
+	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
+
+	.common		= {
+		.reg		= 0x0c4,
+		.hw.init	= CLK_HW_INIT_PARENTS("keypad",
+						      keypad_parents,
+						      &ccu_mp_ops,
+						      0),
+	},
+};
+
+static SUNXI_CCU_GATE(usb_ohci_clk,	"usb-ohci",	"pll-periph",
+		      0x0cc, BIT(6), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"pll-periph",
+		      0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk,	"usb-phy1",	"pll-periph",
+		      0x0cc, BIT(9), 0);
+
+static const char * const gps_parents[] = { "hosc", "pll-periph",
+					    "pll-video1", "pll-ve" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
+				 0x0d0, 0, 3, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(dram_ve_clk,	"dram-ve",	"pll-ddr",
+		      0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,	"dram-csi",	"pll-ddr",
+		      0x100, BIT(1), 0);
+static SUNXI_CCU_GATE(dram_ts_clk,	"dram-ts",	"pll-ddr",
+		      0x100, BIT(3), 0);
+static SUNXI_CCU_GATE(dram_tve_clk,	"dram-tve",	"pll-ddr",
+		      0x100, BIT(5), 0);
+static SUNXI_CCU_GATE(dram_de_fe_clk,	"dram-de-fe",	"pll-ddr",
+		      0x100, BIT(25), 0);
+static SUNXI_CCU_GATE(dram_de_be_clk,	"dram-de-be",	"pll-ddr",
+		      0x100, BIT(26), 0);
+static SUNXI_CCU_GATE(dram_ace_clk,	"dram-ace",	"pll-ddr",
+		      0x100, BIT(29), 0);
+static SUNXI_CCU_GATE(dram_iep_clk,	"dram-iep",	"pll-ddr",
+		      0x100, BIT(31), 0);
+
+static const char * const de_parents[] = { "pll-video0", "pll-video1",
+					   "pll-ddr-other" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
+				 0x104, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
+				 0x10c, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
+					     "pll-video0-2x", "pll-video1-2x" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
+			       0x118, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
+				 tcon_parents,
+				 0x12c, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
+			     0x12c, 11, 1, BIT(15), 0);
+
+static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
+					    "pll-video0-2x", "pll-video1-2x" };
+static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
+				       csi_parents, csi_table,
+				       0x134, 0, 5, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(ve_clk,		"ve",		"pll-ve",
+		      0x13c, BIT(31), 0);
+
+static SUNXI_CCU_GATE(codec_clk,	"codec",	"pll-audio",
+		      0x140, BIT(31), 0);
+
+static SUNXI_CCU_GATE(avs_clk,		"avs",		"hosc",
+		      0x144, BIT(31), 0);
+
+static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
+static const u8 hdmi_table[] = { 0, 2 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
+				       hdmi_parents, hdmi_table,
+				       0x150, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
+					    "pll-ddr-other", "pll-video1",
+					    "pll-video1-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
+				 0x154, 0, 4, 24, 3, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				  0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(iep_clk,		"iep",		"de-be",
+		      0x160, BIT(31), 0);
+
+static struct ccu_common *sun5i_a10s_ccu_clks[] = {
+	&hosc_clk.common,
+	&pll_core_clk.common,
+	&pll_audio_base_clk.common,
+	&pll_video0_clk.common,
+	&pll_ve_clk.common,
+	&pll_ddr_base_clk.common,
+	&pll_ddr_clk.common,
+	&pll_ddr_other_clk.common,
+	&pll_periph_clk.common,
+	&pll_video1_clk.common,
+	&cpu_clk.common,
+	&axi_clk.common,
+	&ahb_clk.common,
+	&apb0_clk.common,
+	&apb1_clk.common,
+	&axi_dram_clk.common,
+	&ahb_otg_clk.common,
+	&ahb_ehci_clk.common,
+	&ahb_ohci_clk.common,
+	&ahb_ss_clk.common,
+	&ahb_dma_clk.common,
+	&ahb_bist_clk.common,
+	&ahb_mmc0_clk.common,
+	&ahb_mmc1_clk.common,
+	&ahb_mmc2_clk.common,
+	&ahb_nand_clk.common,
+	&ahb_sdram_clk.common,
+	&ahb_emac_clk.common,
+	&ahb_ts_clk.common,
+	&ahb_spi0_clk.common,
+	&ahb_spi1_clk.common,
+	&ahb_spi2_clk.common,
+	&ahb_gps_clk.common,
+	&ahb_hstimer_clk.common,
+	&ahb_ve_clk.common,
+	&ahb_tve_clk.common,
+	&ahb_lcd_clk.common,
+	&ahb_csi_clk.common,
+	&ahb_hdmi_clk.common,
+	&ahb_de_be_clk.common,
+	&ahb_de_fe_clk.common,
+	&ahb_iep_clk.common,
+	&ahb_gpu_clk.common,
+	&apb0_codec_clk.common,
+	&apb0_i2s_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb0_keypad_clk.common,
+	&apb1_i2c0_clk.common,
+	&apb1_i2c1_clk.common,
+	&apb1_i2c2_clk.common,
+	&apb1_uart0_clk.common,
+	&apb1_uart1_clk.common,
+	&apb1_uart2_clk.common,
+	&apb1_uart3_clk.common,
+	&nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&mmc2_clk.common,
+	&ts_clk.common,
+	&ss_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&spi2_clk.common,
+	&ir_clk.common,
+	&i2s_clk.common,
+	&keypad_clk.common,
+	&usb_ohci_clk.common,
+	&usb_phy0_clk.common,
+	&usb_phy1_clk.common,
+	&gps_clk.common,
+	&dram_ve_clk.common,
+	&dram_csi_clk.common,
+	&dram_ts_clk.common,
+	&dram_tve_clk.common,
+	&dram_de_fe_clk.common,
+	&dram_de_be_clk.common,
+	&dram_ace_clk.common,
+	&dram_iep_clk.common,
+	&de_be_clk.common,
+	&de_fe_clk.common,
+	&tcon_ch0_clk.common,
+	&tcon_ch1_sclk2_clk.common,
+	&tcon_ch1_sclk1_clk.common,
+	&csi_clk.common,
+	&ve_clk.common,
+	&codec_clk.common,
+	&avs_clk.common,
+	&hdmi_clk.common,
+	&gpu_clk.common,
+	&mbus_clk.common,
+	&iep_clk.common,
+};
+
+static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
+/* We hardcode the divider to 4 for now */
+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
+			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
+			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
+			"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
+			"pll-video0", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
+			"pll-video1", 1, 2, CLK_SET_RATE_PARENT);
+
+static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
+	.hws	= {
+		[CLK_HOSC]		= &hosc_clk.common.hw,
+		[CLK_OSC3M]		= &osc3M_clk.hw,
+		[CLK_PLL_CORE]		= &pll_core_clk.common.hw,
+		[CLK_PLL_AUDIO_BASE]	= &pll_audio_base_clk.common.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.hw,
+		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
+		[CLK_PLL_AUDIO_8X]	= &pll_audio_8x_clk.hw,
+		[CLK_PLL_VIDEO0]	= &pll_video0_clk.common.hw,
+		[CLK_PLL_VIDEO0_2X]	= &pll_video0_2x_clk.hw,
+		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
+		[CLK_PLL_DDR_BASE]	= &pll_ddr_base_clk.common.hw,
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_DDR_OTHER]	= &pll_ddr_other_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.common.hw,
+		[CLK_PLL_VIDEO1]	= &pll_video1_clk.common.hw,
+		[CLK_PLL_VIDEO1_2X]	= &pll_video1_2x_clk.hw,
+		[CLK_CPU]		= &cpu_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_DRAM_AXI]		= &axi_dram_clk.common.hw,
+		[CLK_AHB_OTG]		= &ahb_otg_clk.common.hw,
+		[CLK_AHB_EHCI]		= &ahb_ehci_clk.common.hw,
+		[CLK_AHB_OHCI]		= &ahb_ohci_clk.common.hw,
+		[CLK_AHB_SS]		= &ahb_ss_clk.common.hw,
+		[CLK_AHB_DMA]		= &ahb_dma_clk.common.hw,
+		[CLK_AHB_BIST]		= &ahb_bist_clk.common.hw,
+		[CLK_AHB_MMC0]		= &ahb_mmc0_clk.common.hw,
+		[CLK_AHB_MMC1]		= &ahb_mmc1_clk.common.hw,
+		[CLK_AHB_MMC2]		= &ahb_mmc2_clk.common.hw,
+		[CLK_AHB_NAND]		= &ahb_nand_clk.common.hw,
+		[CLK_AHB_SDRAM]		= &ahb_sdram_clk.common.hw,
+		[CLK_AHB_EMAC]		= &ahb_emac_clk.common.hw,
+		[CLK_AHB_TS]		= &ahb_ts_clk.common.hw,
+		[CLK_AHB_SPI0]		= &ahb_spi0_clk.common.hw,
+		[CLK_AHB_SPI1]		= &ahb_spi1_clk.common.hw,
+		[CLK_AHB_SPI2]		= &ahb_spi2_clk.common.hw,
+		[CLK_AHB_GPS]		= &ahb_gps_clk.common.hw,
+		[CLK_AHB_HSTIMER]	= &ahb_hstimer_clk.common.hw,
+		[CLK_AHB_VE]		= &ahb_ve_clk.common.hw,
+		[CLK_AHB_TVE]		= &ahb_tve_clk.common.hw,
+		[CLK_AHB_LCD]		= &ahb_lcd_clk.common.hw,
+		[CLK_AHB_CSI]		= &ahb_csi_clk.common.hw,
+		[CLK_AHB_HDMI]		= &ahb_hdmi_clk.common.hw,
+		[CLK_AHB_DE_BE]		= &ahb_de_be_clk.common.hw,
+		[CLK_AHB_DE_FE]		= &ahb_de_fe_clk.common.hw,
+		[CLK_AHB_IEP]		= &ahb_iep_clk.common.hw,
+		[CLK_AHB_GPU]		= &ahb_gpu_clk.common.hw,
+		[CLK_APB0_CODEC]	= &apb0_codec_clk.common.hw,
+		[CLK_APB0_I2S]		= &apb0_i2s_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB0_KEYPAD]	= &apb0_keypad_clk.common.hw,
+		[CLK_APB1_I2C0]		= &apb1_i2c0_clk.common.hw,
+		[CLK_APB1_I2C1]		= &apb1_i2c1_clk.common.hw,
+		[CLK_APB1_I2C2]		= &apb1_i2c2_clk.common.hw,
+		[CLK_APB1_UART0]	= &apb1_uart0_clk.common.hw,
+		[CLK_APB1_UART1]	= &apb1_uart1_clk.common.hw,
+		[CLK_APB1_UART2]	= &apb1_uart2_clk.common.hw,
+		[CLK_APB1_UART3]	= &apb1_uart3_clk.common.hw,
+		[CLK_NAND]		= &nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_TS]		= &ts_clk.common.hw,
+		[CLK_SS]		= &ss_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+		[CLK_I2S]		= &i2s_clk.common.hw,
+		[CLK_KEYPAD]		= &keypad_clk.common.hw,
+		[CLK_USB_OHCI]		= &usb_ohci_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_GPS]		= &gps_clk.common.hw,
+		[CLK_DRAM_VE]		= &dram_ve_clk.common.hw,
+		[CLK_DRAM_CSI]		= &dram_csi_clk.common.hw,
+		[CLK_DRAM_TS]		= &dram_ts_clk.common.hw,
+		[CLK_DRAM_TVE]		= &dram_tve_clk.common.hw,
+		[CLK_DRAM_DE_FE]	= &dram_de_fe_clk.common.hw,
+		[CLK_DRAM_DE_BE]	= &dram_de_be_clk.common.hw,
+		[CLK_DRAM_ACE]		= &dram_ace_clk.common.hw,
+		[CLK_DRAM_IEP]		= &dram_iep_clk.common.hw,
+		[CLK_DE_BE]		= &de_be_clk.common.hw,
+		[CLK_DE_FE]		= &de_fe_clk.common.hw,
+		[CLK_TCON_CH0]		= &tcon_ch0_clk.common.hw,
+		[CLK_TCON_CH1_SCLK]	= &tcon_ch1_sclk2_clk.common.hw,
+		[CLK_TCON_CH1]		= &tcon_ch1_sclk1_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_CODEC]		= &codec_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_HDMI]		= &hdmi_clk.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_IEP]		= &iep_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		=  { 0x0cc, BIT(1) },
+
+	[RST_GPS]		=  { 0x0d0, BIT(30) },
+
+	[RST_DE_BE]		=  { 0x104, BIT(30) },
+
+	[RST_DE_FE]		=  { 0x10c, BIT(30) },
+
+	[RST_TVE]		=  { 0x118, BIT(29) },
+	[RST_LCD]		=  { 0x118, BIT(30) },
+
+	[RST_CSI]		=  { 0x134, BIT(30) },
+
+	[RST_VE]		=  { 0x13c, BIT(0) },
+
+	[RST_GPU]		=  { 0x154, BIT(30) },
+
+	[RST_IEP]		=  { 0x160, BIT(30) },
+};
+
+static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
+	.ccu_clks	= sun5i_a10s_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun5i_a10s_ccu_clks),
+
+	.hw_clks	= &sun5i_a10s_hw_clks,
+
+	.resets		= sun5i_a10s_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun5i_a10s_ccu_resets),
+};
+
+static void __init sun5i_a10s_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	/* Force the PLL-Audio-1x divider to 4 */
+	val = readl(reg + SUN5I_PLL_AUDIO_REG);
+	val &= ~GENMASK(19, 16);
+	writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
+
+	/*
+	 * Use the peripheral PLL as the AHB parent, instead of CPU /
+	 * AXI which have rate changes due to cpufreq.
+	 *
+	 * This is especially a big deal for the HS timer whose parent
+	 * clock is AHB.
+	 */
+	val = readl(reg + SUN5I_AHB_REG);
+	val &= ~GENMASK(7, 6);
+	writel(val | (2 << 6), reg + SUN5I_AHB_REG);
+
+	sunxi_ccu_probe(node, reg, &sun5i_a10s_ccu_desc);
+}
+CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
+	       sun5i_a10s_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
new file mode 100644
index 000000000000..43f2ce3e9e6e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2016 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN5I_H_
+#define _CCU_SUN5I_H_
+
+#include <dt-bindings/clock/sun5i-ccu.h>
+#include <dt-bindings/reset/sun5i-ccu.h>
+
+#define CLK_HOSC		1
+#define CLK_OSC3M		2
+#define CLK_PLL_CORE		3
+#define CLK_PLL_AUDIO_BASE	4
+#define CLK_PLL_AUDIO		5
+#define CLK_PLL_AUDIO_2X	6
+#define CLK_PLL_AUDIO_4X	7
+#define CLK_PLL_AUDIO_8X	8
+#define CLK_PLL_VIDEO0		9
+#define CLK_PLL_VIDEO0_2X	10
+#define CLK_PLL_VE		11
+#define CLK_PLL_DDR_BASE	12
+#define CLK_PLL_DDR		13
+#define CLK_PLL_DDR_OTHER	14
+#define CLK_PLL_PERIPH		15
+#define CLK_PLL_VIDEO1		16
+#define CLK_PLL_VIDEO1_2X	17
+#define CLK_OSC24M		18
+#define CLK_CPU			19
+#define CLK_AXI			20
+#define CLK_AHB			21
+#define CLK_APB0		22
+#define CLK_APB1		23
+#define CLK_DRAM_AXI		24
+#define CLK_AHB_OTG		25
+#define CLK_AHB_EHCI		26
+#define CLK_AHB_OHCI		27
+#define CLK_AHB_SS		28
+#define CLK_AHB_DMA		29
+#define CLK_AHB_BIST		30
+#define CLK_AHB_MMC0		31
+#define CLK_AHB_MMC1		32
+#define CLK_AHB_MMC2		33
+#define CLK_AHB_NAND		34
+#define CLK_AHB_SDRAM		35
+#define CLK_AHB_EMAC		36
+#define CLK_AHB_TS		37
+#define CLK_AHB_SPI0		38
+#define CLK_AHB_SPI1		39
+#define CLK_AHB_SPI2		40
+#define CLK_AHB_GPS		41
+#define CLK_AHB_HSTIMER		42
+#define CLK_AHB_VE		43
+#define CLK_AHB_TVE		44
+#define CLK_AHB_LCD		45
+#define CLK_AHB_CSI		46
+#define CLK_AHB_HDMI		47
+#define CLK_AHB_DE_BE		48
+#define CLK_AHB_DE_FE		49
+#define CLK_AHB_IEP		50
+#define CLK_AHB_GPU		51
+#define CLK_APB0_CODEC		52
+#define CLK_APB0_SPDIF		53
+#define CLK_APB0_I2S		54
+#define CLK_APB0_PIO		55
+#define CLK_APB0_IR		56
+#define CLK_APB0_KEYPAD		57
+#define CLK_APB1_I2C0		58
+#define CLK_APB1_I2C1		59
+#define CLK_APB1_I2C2		60
+#define CLK_APB1_UART0		61
+#define CLK_APB1_UART1		62
+#define CLK_APB1_UART2		63
+#define CLK_APB1_UART3		64
+#define CLK_NAND		65
+#define CLK_MMC0		66
+#define CLK_MMC1		67
+#define CLK_MMC2		68
+#define CLK_TS			69
+#define CLK_SS			70
+#define CLK_CE			71
+#define CLK_SPI0		72
+#define CLK_SPI1		73
+#define CLK_SPI2		74
+#define CLK_IR			75
+#define CLK_I2S			76
+#define CLK_SPDIF		77
+#define CLK_KEYPAD		78
+#define CLK_USB_OHCI		79
+#define CLK_USB_PHY0		80
+#define CLK_USB_PHY1		81
+#define CLK_GPS			82
+#define CLK_DRAM_VE		83
+#define CLK_DRAM_CSI		84
+#define CLK_DRAM_TS		85
+#define CLK_DRAM_TVE		86
+#define CLK_DRAM_DE_FE		87
+#define CLK_DRAM_DE_BE		88
+#define CLK_DRAM_ACE		89
+#define CLK_DRAM_IEP		90
+#define CLK_DE_BE		91
+#define CLK_DE_FE		92
+#define CLK_TCON_CH0		93
+#define CLK_TCON_CH1_SCLK	94
+#define CLK_TCON_CH1		95
+#define CLK_CSI			96
+#define CLK_VE			97
+#define CLK_CODEC		98
+#define CLK_AVS			99
+#define CLK_HDMI		100
+#define CLK_GPU			101
+#define CLK_MBUS		102
+#define CLK_IEP			103
+
+#define CLK_NUMBER		(CLK_IEP + 1)
+
+#endif /* _CCU_SUN5I_H_ */
-- 
git-series 0.8.11

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

* [PATCH 7/10] clk: sunxi-ng: Add A13 CCU driver
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (5 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13  9:55   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 8/10] clk: sunxi-ng: Add GR8 driver Maxime Ripard
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/Kconfig         |  10 +-
 drivers/clk/sunxi-ng/Makefile        |   1 +-
 drivers/clk/sunxi-ng/ccu-sun5i-a13.c | 681 ++++++++++++++++++++++++++++-
 3 files changed, 692 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a13.c

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index e2becd36a1f9..5e62e6ad6e08 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -74,6 +74,16 @@ config SUN5I_A10S_CCU
 	select SUNXI_CCU_PHASE
 	default MACH_SUN5I
 
+config SUN5I_A13_CCU
+	bool "Support for the Allwinner A13 CCM"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_NK
+	select SUNXI_CCU_NKM
+	select SUNXI_CCU_NM
+	select SUNXI_CCU_MP
+	select SUNXI_CCU_PHASE
+	default MACH_SUN5I
+
 config SUN6I_A31_CCU
 	bool "Support for the Allwinner A31/A31s CCU"
 	select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 79e9a166dc83..1f03b3d608f2 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SUNXI_CCU_MP)	+= ccu_mp.o
 # SoC support
 obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
 obj-$(CONFIG_SUN5I_A10S_CCU)	+= ccu-sun5i-a10s.o
+obj-$(CONFIG_SUN5I_A13_CCU)	+= ccu-sun5i-a13.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a13.c b/drivers/clk/sunxi-ng/ccu-sun5i-a13.c
new file mode 100644
index 000000000000..7536d5760621
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i-a13.c
@@ -0,0 +1,681 @@
+/*
+ * Copyright (c) 2016 Maxime Ripard. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun5i.h"
+
+static struct ccu_nkmp pll_core_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x000,
+		.hw.init	= CLK_HW_INIT("pll-core",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we just
+ * hardcode it to match with the clock names
+ */
+#define SUN5I_PLL_AUDIO_REG	0x008
+
+static struct ccu_nm pll_audio_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
+	.m		= _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+	.common		= {
+		.reg		= 0x008,
+		.hw.init	= CLK_HW_INIT("pll-audio-base",
+					      "hosc",
+					      &ccu_nm_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video0_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+					  270000000, 297000000),
+	.common		= {
+		.reg		= 0x010,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video0",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static struct ccu_nkmp pll_ve_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x018,
+		.hw.init	= CLK_HW_INIT("pll-ve",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_ddr_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-base",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
+
+static struct ccu_div pll_ddr_other_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
+					      &ccu_div_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_periph_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.fixed_post_div	= 2,
+	.common		= {
+		.reg		= 0x028,
+		.features	= CCU_FEATURE_FIXED_POSTDIV,
+		.hw.init	= CLK_HW_INIT("pll-periph",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video1_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+				  270000000, 297000000),
+	.common		= {
+		.reg		= 0x030,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video1",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_GATE(hosc_clk,	"hosc",	"osc24M", 0x050, BIT(0), 0);
+
+#define SUN5I_AHB_REG	0x054
+static const char * const cpu_parents[] = { "osc32k", "hosc",
+					    "pll-core" , "pll-periph" };
+static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
+	{ .index = 3, .div = 3, },
+};
+static struct ccu_mux cpu_clk = {
+	.mux		= {
+		.shift		= 16,
+		.width		= 2,
+		.fixed_predivs	= cpu_predivs,
+		.n_predivs	= ARRAY_SIZE(cpu_predivs),
+	},
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("cpu",
+						      cpu_parents,
+						      &ccu_mux_ops,
+						      CLK_IS_CRITICAL),
+	}
+};
+
+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
+
+static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
+static struct ccu_div ahb_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+	.mux		= _SUNXI_CCU_MUX(6, 2),
+
+	.common		= {
+		.reg		= 0x054,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb",
+						      ahb_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static struct clk_div_table apb0_div_table[] = {
+	{ .val = 0, .div = 2 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ /* Sentinel */ },
+};
+static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
+			   0x054, 8, 2, apb0_div_table, 0);
+
+static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(axi_dram_clk,	"axi-dram",	"axi",
+		      0x05c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(ahb_otg_clk,	"ahb-otg",	"ahb",
+		      0x060, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_ehci_clk,	"ahb-ehci",	"ahb",
+		      0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(ahb_ohci_clk,	"ahb-ohci",	"ahb",
+		      0x060, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_ss_clk,	"ahb-ss",	"ahb",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(ahb_dma_clk,	"ahb-dma",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_bist_clk,	"ahb-bist",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_mmc0_clk,	"ahb-mmc0",	"ahb",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_mmc1_clk,	"ahb-mmc1",	"ahb",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(ahb_mmc2_clk,	"ahb-mmc2",	"ahb",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(ahb_nand_clk,	"ahb-nand",	"ahb",
+		      0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(ahb_sdram_clk,	"ahb-sdram",	"ahb",
+		      0x060, BIT(14), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE(ahb_emac_clk,	"ahb-emac",	"ahb",
+		      0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(ahb_spi0_clk,	"ahb-spi0",	"ahb",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(ahb_spi1_clk,	"ahb-spi1",	"ahb",
+		      0x060, BIT(21), 0);
+static SUNXI_CCU_GATE(ahb_spi2_clk,	"ahb-spi2",	"ahb",
+		      0x060, BIT(22), 0);
+static SUNXI_CCU_GATE(ahb_hstimer_clk,	"ahb-hstimer",	"ahb",
+		      0x060, BIT(28), 0);
+
+static SUNXI_CCU_GATE(ahb_ve_clk,	"ahb-ve",	"ahb",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_tve_clk,	"ahb-tve",	"ahb",
+		      0x064, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_lcd_clk,	"ahb-lcd",	"ahb",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(ahb_csi_clk,	"ahb-csi",	"ahb",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_de_be_clk,	"ahb-de-be",	"ahb",
+		      0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(ahb_de_fe_clk,	"ahb-de-fe",	"ahb",
+		      0x064, BIT(14), 0);
+static SUNXI_CCU_GATE(ahb_iep_clk,	"ahb-iep",	"ahb",
+		      0x064, BIT(19), 0);
+static SUNXI_CCU_GATE(ahb_gpu_clk,	"ahb-gpu",	"ahb",
+		      0x064, BIT(20), 0);
+
+static SUNXI_CCU_GATE(apb0_codec_clk,	"apb0-codec",	"apb0",
+		      0x068, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
+		      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
+		      0x068, BIT(6), 0);
+
+static SUNXI_CCU_GATE(apb1_i2c0_clk,	"apb1-i2c0",	"apb1",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(apb1_i2c1_clk,	"apb1-i2c1",	"apb1",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(apb1_i2c2_clk,	"apb1-i2c2",	"apb1",
+		      0x06c, BIT(2), 0);
+static SUNXI_CCU_GATE(apb1_uart0_clk,	"apb1-uart0",	"apb1",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(apb1_uart1_clk,	"apb1-uart1",	"apb1",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(apb1_uart2_clk,	"apb1-uart2",	"apb1",
+		      0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(apb1_uart3_clk,	"apb1-uart3",	"apb1",
+		      0x06c, BIT(19), 0);
+
+static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
+						     "pll-ddr-other" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(usb_ohci_clk,	"usb-ohci",	"pll-periph",
+		      0x0cc, BIT(6), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"pll-periph",
+		      0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk,	"usb-phy1",	"pll-periph",
+		      0x0cc, BIT(9), 0);
+
+static SUNXI_CCU_GATE(dram_ve_clk,	"dram-ve",	"pll-ddr",
+		      0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,	"dram-csi",	"pll-ddr",
+		      0x100, BIT(1), 0);
+static SUNXI_CCU_GATE(dram_tve_clk,	"dram-tve",	"pll-ddr",
+		      0x100, BIT(5), 0);
+static SUNXI_CCU_GATE(dram_de_fe_clk,	"dram-de-fe",	"pll-ddr",
+		      0x100, BIT(25), 0);
+static SUNXI_CCU_GATE(dram_de_be_clk,	"dram-de-be",	"pll-ddr",
+		      0x100, BIT(26), 0);
+static SUNXI_CCU_GATE(dram_ace_clk,	"dram-ace",	"pll-ddr",
+		      0x100, BIT(29), 0);
+static SUNXI_CCU_GATE(dram_iep_clk,	"dram-iep",	"pll-ddr",
+		      0x100, BIT(31), 0);
+
+static const char * const de_parents[] = { "pll-video0", "pll-video1",
+					   "pll-ddr-other" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
+				 0x104, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
+				 0x10c, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
+					     "pll-video0-2x", "pll-video1-2x" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
+			       0x118, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
+				 tcon_parents,
+				 0x12c, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
+			     0x12c, 11, 1, BIT(15), 0);
+
+static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
+					    "pll-video0-2x", "pll-video1-2x" };
+static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
+				       csi_parents, csi_table,
+				       0x134, 0, 5, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(ve_clk,		"ve",		"pll-ve",
+		      0x13c, BIT(31), 0);
+
+static SUNXI_CCU_GATE(codec_clk,	"codec",	"pll-audio",
+		      0x140, BIT(31), 0);
+
+static SUNXI_CCU_GATE(avs_clk,		"avs",		"hosc",
+		      0x144, BIT(31), 0);
+
+static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
+					    "pll-ddr-other", "pll-video1",
+					    "pll-video1-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
+				 0x154, 0, 4, 24, 3, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				  0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(iep_clk,		"iep",		"de-be",
+		      0x160, BIT(31), 0);
+
+static struct ccu_common *sun5i_a13_ccu_clks[] = {
+	&hosc_clk.common,
+	&pll_core_clk.common,
+	&pll_audio_base_clk.common,
+	&pll_video0_clk.common,
+	&pll_ve_clk.common,
+	&pll_ddr_base_clk.common,
+	&pll_ddr_clk.common,
+	&pll_ddr_other_clk.common,
+	&pll_periph_clk.common,
+	&pll_video1_clk.common,
+	&cpu_clk.common,
+	&axi_clk.common,
+	&ahb_clk.common,
+	&apb0_clk.common,
+	&apb1_clk.common,
+	&axi_dram_clk.common,
+	&ahb_otg_clk.common,
+	&ahb_ehci_clk.common,
+	&ahb_ohci_clk.common,
+	&ahb_ss_clk.common,
+	&ahb_dma_clk.common,
+	&ahb_bist_clk.common,
+	&ahb_mmc0_clk.common,
+	&ahb_mmc1_clk.common,
+	&ahb_mmc2_clk.common,
+	&ahb_nand_clk.common,
+	&ahb_sdram_clk.common,
+	&ahb_emac_clk.common,
+	&ahb_spi0_clk.common,
+	&ahb_spi1_clk.common,
+	&ahb_spi2_clk.common,
+	&ahb_hstimer_clk.common,
+	&ahb_ve_clk.common,
+	&ahb_tve_clk.common,
+	&ahb_lcd_clk.common,
+	&ahb_csi_clk.common,
+	&ahb_de_be_clk.common,
+	&ahb_de_fe_clk.common,
+	&ahb_iep_clk.common,
+	&ahb_gpu_clk.common,
+	&apb0_codec_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb1_i2c0_clk.common,
+	&apb1_i2c1_clk.common,
+	&apb1_i2c2_clk.common,
+	&apb1_uart0_clk.common,
+	&apb1_uart1_clk.common,
+	&apb1_uart2_clk.common,
+	&apb1_uart3_clk.common,
+	&nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&mmc2_clk.common,
+	&ss_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&spi2_clk.common,
+	&ir_clk.common,
+	&usb_ohci_clk.common,
+	&usb_phy0_clk.common,
+	&usb_phy1_clk.common,
+	&dram_ve_clk.common,
+	&dram_csi_clk.common,
+	&dram_tve_clk.common,
+	&dram_de_fe_clk.common,
+	&dram_de_be_clk.common,
+	&dram_ace_clk.common,
+	&dram_iep_clk.common,
+	&de_be_clk.common,
+	&de_fe_clk.common,
+	&tcon_ch0_clk.common,
+	&tcon_ch1_sclk2_clk.common,
+	&tcon_ch1_sclk1_clk.common,
+	&csi_clk.common,
+	&ve_clk.common,
+	&codec_clk.common,
+	&avs_clk.common,
+	&gpu_clk.common,
+	&mbus_clk.common,
+	&iep_clk.common,
+};
+
+static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
+/* We hardcode the divider to 4 for now */
+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
+			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
+			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
+			"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
+			"pll-video0", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
+			"pll-video1", 1, 2, CLK_SET_RATE_PARENT);
+
+static struct clk_hw_onecell_data sun5i_a13_hw_clks = {
+	.hws	= {
+		[CLK_HOSC]		= &hosc_clk.common.hw,
+		[CLK_OSC3M]		= &osc3M_clk.hw,
+		[CLK_PLL_CORE]		= &pll_core_clk.common.hw,
+		[CLK_PLL_AUDIO_BASE]	= &pll_audio_base_clk.common.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.hw,
+		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
+		[CLK_PLL_AUDIO_8X]	= &pll_audio_8x_clk.hw,
+		[CLK_PLL_VIDEO0]	= &pll_video0_clk.common.hw,
+		[CLK_PLL_VIDEO0_2X]	= &pll_video0_2x_clk.hw,
+		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
+		[CLK_PLL_DDR_BASE]	= &pll_ddr_base_clk.common.hw,
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_DDR_OTHER]	= &pll_ddr_other_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.common.hw,
+		[CLK_PLL_VIDEO1]	= &pll_video1_clk.common.hw,
+		[CLK_PLL_VIDEO1_2X]	= &pll_video1_2x_clk.hw,
+		[CLK_CPU]		= &cpu_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_DRAM_AXI]		= &axi_dram_clk.common.hw,
+		[CLK_AHB_OTG]		= &ahb_otg_clk.common.hw,
+		[CLK_AHB_EHCI]		= &ahb_ehci_clk.common.hw,
+		[CLK_AHB_OHCI]		= &ahb_ohci_clk.common.hw,
+		[CLK_AHB_SS]		= &ahb_ss_clk.common.hw,
+		[CLK_AHB_DMA]		= &ahb_dma_clk.common.hw,
+		[CLK_AHB_BIST]		= &ahb_bist_clk.common.hw,
+		[CLK_AHB_MMC0]		= &ahb_mmc0_clk.common.hw,
+		[CLK_AHB_MMC1]		= &ahb_mmc1_clk.common.hw,
+		[CLK_AHB_MMC2]		= &ahb_mmc2_clk.common.hw,
+		[CLK_AHB_NAND]		= &ahb_nand_clk.common.hw,
+		[CLK_AHB_SDRAM]		= &ahb_sdram_clk.common.hw,
+		[CLK_AHB_EMAC]		= &ahb_emac_clk.common.hw,
+		[CLK_AHB_SPI0]		= &ahb_spi0_clk.common.hw,
+		[CLK_AHB_SPI1]		= &ahb_spi1_clk.common.hw,
+		[CLK_AHB_SPI2]		= &ahb_spi2_clk.common.hw,
+		[CLK_AHB_HSTIMER]	= &ahb_hstimer_clk.common.hw,
+		[CLK_AHB_VE]		= &ahb_ve_clk.common.hw,
+		[CLK_AHB_TVE]		= &ahb_tve_clk.common.hw,
+		[CLK_AHB_LCD]		= &ahb_lcd_clk.common.hw,
+		[CLK_AHB_CSI]		= &ahb_csi_clk.common.hw,
+		[CLK_AHB_DE_BE]		= &ahb_de_be_clk.common.hw,
+		[CLK_AHB_DE_FE]		= &ahb_de_fe_clk.common.hw,
+		[CLK_AHB_IEP]		= &ahb_iep_clk.common.hw,
+		[CLK_AHB_GPU]		= &ahb_gpu_clk.common.hw,
+		[CLK_APB0_CODEC]	= &apb0_codec_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB1_I2C0]		= &apb1_i2c0_clk.common.hw,
+		[CLK_APB1_I2C1]		= &apb1_i2c1_clk.common.hw,
+		[CLK_APB1_I2C2]		= &apb1_i2c2_clk.common.hw,
+		[CLK_APB1_UART0]	= &apb1_uart0_clk.common.hw,
+		[CLK_APB1_UART1]	= &apb1_uart1_clk.common.hw,
+		[CLK_APB1_UART2]	= &apb1_uart2_clk.common.hw,
+		[CLK_APB1_UART3]	= &apb1_uart3_clk.common.hw,
+		[CLK_NAND]		= &nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_SS]		= &ss_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+		[CLK_USB_OHCI]		= &usb_ohci_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_DRAM_VE]		= &dram_ve_clk.common.hw,
+		[CLK_DRAM_CSI]		= &dram_csi_clk.common.hw,
+		[CLK_DRAM_TVE]		= &dram_tve_clk.common.hw,
+		[CLK_DRAM_DE_FE]	= &dram_de_fe_clk.common.hw,
+		[CLK_DRAM_DE_BE]	= &dram_de_be_clk.common.hw,
+		[CLK_DRAM_ACE]		= &dram_ace_clk.common.hw,
+		[CLK_DRAM_IEP]		= &dram_iep_clk.common.hw,
+		[CLK_DE_BE]		= &de_be_clk.common.hw,
+		[CLK_DE_FE]		= &de_fe_clk.common.hw,
+		[CLK_TCON_CH0]		= &tcon_ch0_clk.common.hw,
+		[CLK_TCON_CH1_SCLK]	= &tcon_ch1_sclk2_clk.common.hw,
+		[CLK_TCON_CH1]		= &tcon_ch1_sclk1_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_CODEC]		= &codec_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_IEP]		= &iep_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun5i_a13_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		=  { 0x0cc, BIT(1) },
+
+	[RST_GPS]		=  { 0x0d0, BIT(30) },
+
+	[RST_DE_BE]		=  { 0x104, BIT(30) },
+
+	[RST_DE_FE]		=  { 0x10c, BIT(30) },
+
+	[RST_TVE]		=  { 0x118, BIT(29) },
+	[RST_LCD]		=  { 0x118, BIT(30) },
+
+	[RST_CSI]		=  { 0x134, BIT(30) },
+
+	[RST_VE]		=  { 0x13c, BIT(0) },
+
+	[RST_GPU]		=  { 0x154, BIT(30) },
+
+	[RST_IEP]		=  { 0x160, BIT(30) },
+};
+
+static const struct sunxi_ccu_desc sun5i_a13_ccu_desc = {
+	.ccu_clks	= sun5i_a13_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun5i_a13_ccu_clks),
+
+	.hw_clks	= &sun5i_a13_hw_clks,
+
+	.resets		= sun5i_a13_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun5i_a13_ccu_resets),
+};
+
+static void __init sun5i_a13_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	/* Force the PLL-Audio-1x divider to 4 */
+	val = readl(reg + SUN5I_PLL_AUDIO_REG);
+	val &= ~GENMASK(19, 16);
+	writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
+
+	/*
+	 * Use the peripheral PLL as the AHB parent, instead of CPU /
+	 * AXI which have rate changes due to cpufreq.
+	 *
+	 * This is especially a big deal for the HS timer whose parent
+	 * clock is AHB.
+	 */
+	val = readl(reg + SUN5I_AHB_REG);
+	val &= ~GENMASK(7, 6);
+	writel(val | (2 << 6), reg + SUN5I_AHB_REG);
+
+	sunxi_ccu_probe(node, reg, &sun5i_a13_ccu_desc);
+}
+CLK_OF_DECLARE(sun5i_a13_ccu, "allwinner,sun5i-a13-ccu",
+	       sun5i_a13_ccu_setup);
-- 
git-series 0.8.11

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

* [PATCH 8/10] clk: sunxi-ng: Add GR8 driver
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (6 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 7/10] clk: sunxi-ng: Add A13 " Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-08 17:23 ` [PATCH 9/10] ARM: sun5i: Convert to CCU Maxime Ripard
  2016-11-08 17:23 ` [PATCH 10/10] ARM: gr8: " Maxime Ripard
  9 siblings, 0 replies; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/Kconfig         |  10 +-
 drivers/clk/sunxi-ng/Makefile        |   1 +-
 drivers/clk/sunxi-ng/ccu-sun5i-gr8.c | 684 ++++++++++++++++++++++++++++-
 3 files changed, 695 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-gr8.c

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 5e62e6ad6e08..43f2096b9894 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -84,6 +84,16 @@ config SUN5I_A13_CCU
 	select SUNXI_CCU_PHASE
 	default MACH_SUN5I
 
+config SUN5I_GR8_CCU
+	bool "Support for the NextThing GR8 CCM"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_NK
+	select SUNXI_CCU_NKM
+	select SUNXI_CCU_NM
+	select SUNXI_CCU_MP
+	select SUNXI_CCU_PHASE
+	default MACH_SUN5I
+
 config SUN6I_A31_CCU
 	bool "Support for the Allwinner A31/A31s CCU"
 	select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 1f03b3d608f2..bbdce44c145b 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SUNXI_CCU_MP)	+= ccu_mp.o
 obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
 obj-$(CONFIG_SUN5I_A10S_CCU)	+= ccu-sun5i-a10s.o
 obj-$(CONFIG_SUN5I_A13_CCU)	+= ccu-sun5i-a13.o
+obj-$(CONFIG_SUN5I_GR8_CCU)	+= ccu-sun5i-gr8.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-gr8.c b/drivers/clk/sunxi-ng/ccu-sun5i-gr8.c
new file mode 100644
index 000000000000..9c1169d0406e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i-gr8.c
@@ -0,0 +1,684 @@
+/*
+ * Copyright (c) 2016 Maxime Ripard. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun5i.h"
+
+static struct ccu_nkmp pll_core_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x000,
+		.hw.init	= CLK_HW_INIT("pll-core",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we just
+ * hardcode it to match with the clock names
+ */
+#define SUN5I_PLL_AUDIO_REG	0x008
+
+static struct ccu_nm pll_audio_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
+	.m		= _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+	.common		= {
+		.reg		= 0x008,
+		.hw.init	= CLK_HW_INIT("pll-audio-base",
+					      "hosc",
+					      &ccu_nm_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video0_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+					  270000000, 297000000),
+	.common		= {
+		.reg		= 0x010,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video0",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static struct ccu_nkmp pll_ve_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x018,
+		.hw.init	= CLK_HW_INIT("pll-ve",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_ddr_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-base",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
+
+static struct ccu_div pll_ddr_other_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
+					      &ccu_div_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_periph_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.fixed_post_div	= 2,
+	.common		= {
+		.reg		= 0x028,
+		.features	= CCU_FEATURE_FIXED_POSTDIV,
+		.hw.init	= CLK_HW_INIT("pll-periph",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video1_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+				  270000000, 297000000),
+	.common		= {
+		.reg		= 0x030,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video1",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_GATE(hosc_clk,	"hosc",	"osc24M", 0x050, BIT(0), 0);
+
+#define SUN5I_AHB_REG	0x054
+static const char * const cpu_parents[] = { "osc32k", "hosc",
+					    "pll-core" , "pll-periph" };
+static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
+	{ .index = 3, .div = 3, },
+};
+static struct ccu_mux cpu_clk = {
+	.mux		= {
+		.shift		= 16,
+		.width		= 2,
+		.fixed_predivs	= cpu_predivs,
+		.n_predivs	= ARRAY_SIZE(cpu_predivs),
+	},
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("cpu",
+						      cpu_parents,
+						      &ccu_mux_ops,
+						      CLK_IS_CRITICAL),
+	}
+};
+
+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
+
+static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
+static struct ccu_div ahb_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+	.mux		= _SUNXI_CCU_MUX(6, 2),
+
+	.common		= {
+		.reg		= 0x054,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb",
+						      ahb_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static struct clk_div_table apb0_div_table[] = {
+	{ .val = 0, .div = 2 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ /* Sentinel */ },
+};
+static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
+			   0x054, 8, 2, apb0_div_table, 0);
+
+static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(axi_dram_clk,	"axi-dram",	"axi",
+		      0x05c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(ahb_otg_clk,	"ahb-otg",	"ahb",
+		      0x060, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_ehci_clk,	"ahb-ehci",	"ahb",
+		      0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(ahb_ohci_clk,	"ahb-ohci",	"ahb",
+		      0x060, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_ss_clk,	"ahb-ss",	"ahb",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(ahb_dma_clk,	"ahb-dma",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_bist_clk,	"ahb-bist",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_mmc0_clk,	"ahb-mmc0",	"ahb",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_mmc1_clk,	"ahb-mmc1",	"ahb",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(ahb_mmc2_clk,	"ahb-mmc2",	"ahb",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(ahb_nand_clk,	"ahb-nand",	"ahb",
+		      0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(ahb_sdram_clk,	"ahb-sdram",	"ahb",
+		      0x060, BIT(14), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE(ahb_spi0_clk,	"ahb-spi0",	"ahb",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(ahb_spi2_clk,	"ahb-spi2",	"ahb",
+		      0x060, BIT(22), 0);
+static SUNXI_CCU_GATE(ahb_hstimer_clk,	"ahb-hstimer",	"ahb",
+		      0x060, BIT(28), 0);
+
+static SUNXI_CCU_GATE(ahb_ve_clk,	"ahb-ve",	"ahb",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_tve_clk,	"ahb-tve",	"ahb",
+		      0x064, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_lcd_clk,	"ahb-lcd",	"ahb",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(ahb_csi_clk,	"ahb-csi",	"ahb",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_de_be_clk,	"ahb-de-be",	"ahb",
+		      0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(ahb_de_fe_clk,	"ahb-de-fe",	"ahb",
+		      0x064, BIT(14), 0);
+static SUNXI_CCU_GATE(ahb_iep_clk,	"ahb-iep",	"ahb",
+		      0x064, BIT(19), 0);
+static SUNXI_CCU_GATE(ahb_gpu_clk,	"ahb-gpu",	"ahb",
+		      0x064, BIT(20), 0);
+
+static SUNXI_CCU_GATE(apb0_codec_clk,	"apb0-codec",	"apb0",
+		      0x068, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_spdif_clk,	"apb0-spdif",	"apb0",
+		      0x068, BIT(1), 0);
+static SUNXI_CCU_GATE(apb0_i2s_clk,	"apb0-i2s",	"apb0",
+		      0x068, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
+		      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
+		      0x068, BIT(6), 0);
+
+static SUNXI_CCU_GATE(apb1_i2c0_clk,	"apb1-i2c0",	"apb1",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(apb1_i2c1_clk,	"apb1-i2c1",	"apb1",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(apb1_i2c2_clk,	"apb1-i2c2",	"apb1",
+		      0x06c, BIT(2), 0);
+static SUNXI_CCU_GATE(apb1_uart0_clk,	"apb1-uart0",	"apb1",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(apb1_uart1_clk,	"apb1-uart1",	"apb1",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(apb1_uart2_clk,	"apb1-uart2",	"apb1",
+		      0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(apb1_uart3_clk,	"apb1-uart3",	"apb1",
+		      0x06c, BIT(19), 0);
+
+static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
+						     "pll-ddr-other" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
+					    "pll-audio-2x", "pll-audio" };
+static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
+			       0x0b8, 16, 2, BIT(31), 0);
+
+static const char * const spdif_parents[] = { "pll-audio-8x", "pll-audio-4x",
+					    "pll-audio-2x", "pll-audio" };
+static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", spdif_parents,
+			       0x0c0, 16, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(usb_ohci_clk,	"usb-ohci",	"pll-periph",
+		      0x0cc, BIT(6), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"pll-periph",
+		      0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk,	"usb-phy1",	"pll-periph",
+		      0x0cc, BIT(9), 0);
+
+static SUNXI_CCU_GATE(dram_ve_clk,	"dram-ve",	"pll-ddr",
+		      0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,	"dram-csi",	"pll-ddr",
+		      0x100, BIT(1), 0);
+static SUNXI_CCU_GATE(dram_tve_clk,	"dram-tve",	"pll-ddr",
+		      0x100, BIT(5), 0);
+static SUNXI_CCU_GATE(dram_de_fe_clk,	"dram-de-fe",	"pll-ddr",
+		      0x100, BIT(25), 0);
+static SUNXI_CCU_GATE(dram_de_be_clk,	"dram-de-be",	"pll-ddr",
+		      0x100, BIT(26), 0);
+static SUNXI_CCU_GATE(dram_ace_clk,	"dram-ace",	"pll-ddr",
+		      0x100, BIT(29), 0);
+static SUNXI_CCU_GATE(dram_iep_clk,	"dram-iep",	"pll-ddr",
+		      0x100, BIT(31), 0);
+
+static const char * const de_parents[] = { "pll-video0", "pll-video1",
+					   "pll-ddr-other" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
+				 0x104, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
+				 0x10c, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
+					     "pll-video0-2x", "pll-video1-2x" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
+			       0x118, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
+				 tcon_parents,
+				 0x12c, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
+			     0x12c, 11, 1, BIT(15), 0);
+
+static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
+					    "pll-video0-2x", "pll-video1-2x" };
+static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
+				       csi_parents, csi_table,
+				       0x134, 0, 5, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(ve_clk,		"ve",		"pll-ve",
+		      0x13c, BIT(31), 0);
+
+static SUNXI_CCU_GATE(codec_clk,	"codec",	"pll-audio",
+		      0x140, BIT(31), 0);
+
+static SUNXI_CCU_GATE(avs_clk,		"avs",		"hosc",
+		      0x144, BIT(31), 0);
+
+static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
+					    "pll-ddr-other", "pll-video1",
+					    "pll-video1-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
+				 0x154, 0, 4, 24, 3, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				  0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(iep_clk,		"iep",		"de-be",
+		      0x160, BIT(31), 0);
+
+static struct ccu_common *sun5i_gr8_ccu_clks[] = {
+	&hosc_clk.common,
+	&pll_core_clk.common,
+	&pll_audio_base_clk.common,
+	&pll_video0_clk.common,
+	&pll_ve_clk.common,
+	&pll_ddr_base_clk.common,
+	&pll_ddr_clk.common,
+	&pll_ddr_other_clk.common,
+	&pll_periph_clk.common,
+	&pll_video1_clk.common,
+	&cpu_clk.common,
+	&axi_clk.common,
+	&ahb_clk.common,
+	&apb0_clk.common,
+	&apb1_clk.common,
+	&axi_dram_clk.common,
+	&ahb_otg_clk.common,
+	&ahb_ehci_clk.common,
+	&ahb_ohci_clk.common,
+	&ahb_ss_clk.common,
+	&ahb_dma_clk.common,
+	&ahb_bist_clk.common,
+	&ahb_mmc0_clk.common,
+	&ahb_mmc1_clk.common,
+	&ahb_mmc2_clk.common,
+	&ahb_nand_clk.common,
+	&ahb_sdram_clk.common,
+	&ahb_spi0_clk.common,
+	&ahb_spi2_clk.common,
+	&ahb_hstimer_clk.common,
+	&ahb_ve_clk.common,
+	&ahb_tve_clk.common,
+	&ahb_lcd_clk.common,
+	&ahb_csi_clk.common,
+	&ahb_de_be_clk.common,
+	&ahb_de_fe_clk.common,
+	&ahb_iep_clk.common,
+	&ahb_gpu_clk.common,
+	&apb0_codec_clk.common,
+	&apb0_spdif_clk.common,
+	&apb0_i2s_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb1_i2c0_clk.common,
+	&apb1_i2c1_clk.common,
+	&apb1_i2c2_clk.common,
+	&apb1_uart0_clk.common,
+	&apb1_uart1_clk.common,
+	&apb1_uart2_clk.common,
+	&apb1_uart3_clk.common,
+	&nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&mmc2_clk.common,
+	&ss_clk.common,
+	&spi0_clk.common,
+	&spi2_clk.common,
+	&ir_clk.common,
+	&i2s_clk.common,
+	&spdif_clk.common,
+	&usb_ohci_clk.common,
+	&usb_phy0_clk.common,
+	&usb_phy1_clk.common,
+	&dram_ve_clk.common,
+	&dram_csi_clk.common,
+	&dram_tve_clk.common,
+	&dram_de_fe_clk.common,
+	&dram_de_be_clk.common,
+	&dram_ace_clk.common,
+	&dram_iep_clk.common,
+	&de_be_clk.common,
+	&de_fe_clk.common,
+	&tcon_ch0_clk.common,
+	&tcon_ch1_sclk2_clk.common,
+	&tcon_ch1_sclk1_clk.common,
+	&csi_clk.common,
+	&ve_clk.common,
+	&codec_clk.common,
+	&avs_clk.common,
+	&gpu_clk.common,
+	&mbus_clk.common,
+	&iep_clk.common,
+};
+
+static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
+/* We hardcode the divider to 4 for now */
+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
+			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
+			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
+			"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
+			"pll-video0", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
+			"pll-video1", 1, 2, CLK_SET_RATE_PARENT);
+
+static struct clk_hw_onecell_data sun5i_gr8_hw_clks = {
+	.hws	= {
+		[CLK_HOSC]		= &hosc_clk.common.hw,
+		[CLK_OSC3M]		= &osc3M_clk.hw,
+		[CLK_PLL_CORE]		= &pll_core_clk.common.hw,
+		[CLK_PLL_AUDIO_BASE]	= &pll_audio_base_clk.common.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.hw,
+		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
+		[CLK_PLL_AUDIO_8X]	= &pll_audio_8x_clk.hw,
+		[CLK_PLL_VIDEO0]	= &pll_video0_clk.common.hw,
+		[CLK_PLL_VIDEO0_2X]	= &pll_video0_2x_clk.hw,
+		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
+		[CLK_PLL_DDR_BASE]	= &pll_ddr_base_clk.common.hw,
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_DDR_OTHER]	= &pll_ddr_other_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.common.hw,
+		[CLK_PLL_VIDEO1]	= &pll_video1_clk.common.hw,
+		[CLK_PLL_VIDEO1_2X]	= &pll_video1_2x_clk.hw,
+		[CLK_CPU]		= &cpu_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_DRAM_AXI]		= &axi_dram_clk.common.hw,
+		[CLK_AHB_OTG]		= &ahb_otg_clk.common.hw,
+		[CLK_AHB_EHCI]		= &ahb_ehci_clk.common.hw,
+		[CLK_AHB_OHCI]		= &ahb_ohci_clk.common.hw,
+		[CLK_AHB_SS]		= &ahb_ss_clk.common.hw,
+		[CLK_AHB_DMA]		= &ahb_dma_clk.common.hw,
+		[CLK_AHB_BIST]		= &ahb_bist_clk.common.hw,
+		[CLK_AHB_MMC0]		= &ahb_mmc0_clk.common.hw,
+		[CLK_AHB_MMC1]		= &ahb_mmc1_clk.common.hw,
+		[CLK_AHB_MMC2]		= &ahb_mmc2_clk.common.hw,
+		[CLK_AHB_NAND]		= &ahb_nand_clk.common.hw,
+		[CLK_AHB_SDRAM]		= &ahb_sdram_clk.common.hw,
+		[CLK_AHB_SPI0]		= &ahb_spi0_clk.common.hw,
+		[CLK_AHB_SPI2]		= &ahb_spi2_clk.common.hw,
+		[CLK_AHB_HSTIMER]	= &ahb_hstimer_clk.common.hw,
+		[CLK_AHB_VE]		= &ahb_ve_clk.common.hw,
+		[CLK_AHB_TVE]		= &ahb_tve_clk.common.hw,
+		[CLK_AHB_LCD]		= &ahb_lcd_clk.common.hw,
+		[CLK_AHB_CSI]		= &ahb_csi_clk.common.hw,
+		[CLK_AHB_DE_BE]		= &ahb_de_be_clk.common.hw,
+		[CLK_AHB_DE_FE]		= &ahb_de_fe_clk.common.hw,
+		[CLK_AHB_IEP]		= &ahb_iep_clk.common.hw,
+		[CLK_AHB_GPU]		= &ahb_gpu_clk.common.hw,
+		[CLK_APB0_CODEC]	= &apb0_codec_clk.common.hw,
+		[CLK_APB0_SPDIF]	= &apb0_spdif_clk.common.hw,
+		[CLK_APB0_I2S]		= &apb0_i2s_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB1_I2C0]		= &apb1_i2c0_clk.common.hw,
+		[CLK_APB1_I2C1]		= &apb1_i2c1_clk.common.hw,
+		[CLK_APB1_I2C2]		= &apb1_i2c2_clk.common.hw,
+		[CLK_APB1_UART0]	= &apb1_uart0_clk.common.hw,
+		[CLK_APB1_UART1]	= &apb1_uart1_clk.common.hw,
+		[CLK_APB1_UART2]	= &apb1_uart2_clk.common.hw,
+		[CLK_APB1_UART3]	= &apb1_uart3_clk.common.hw,
+		[CLK_NAND]		= &nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_SS]		= &ss_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+		[CLK_I2S]		= &i2s_clk.common.hw,
+		[CLK_SPDIF]		= &spdif_clk.common.hw,
+		[CLK_USB_OHCI]		= &usb_ohci_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_DRAM_VE]		= &dram_ve_clk.common.hw,
+		[CLK_DRAM_CSI]		= &dram_csi_clk.common.hw,
+		[CLK_DRAM_TVE]		= &dram_tve_clk.common.hw,
+		[CLK_DRAM_DE_FE]	= &dram_de_fe_clk.common.hw,
+		[CLK_DRAM_DE_BE]	= &dram_de_be_clk.common.hw,
+		[CLK_DRAM_ACE]		= &dram_ace_clk.common.hw,
+		[CLK_DRAM_IEP]		= &dram_iep_clk.common.hw,
+		[CLK_DE_BE]		= &de_be_clk.common.hw,
+		[CLK_DE_FE]		= &de_fe_clk.common.hw,
+		[CLK_TCON_CH0]		= &tcon_ch0_clk.common.hw,
+		[CLK_TCON_CH1_SCLK]	= &tcon_ch1_sclk2_clk.common.hw,
+		[CLK_TCON_CH1]		= &tcon_ch1_sclk1_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_CODEC]		= &codec_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_IEP]		= &iep_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun5i_gr8_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		=  { 0x0cc, BIT(1) },
+
+	[RST_DE_BE]		=  { 0x104, BIT(30) },
+
+	[RST_DE_FE]		=  { 0x10c, BIT(30) },
+
+	[RST_TVE]		=  { 0x118, BIT(29) },
+	[RST_LCD]		=  { 0x118, BIT(30) },
+
+	[RST_CSI]		=  { 0x134, BIT(30) },
+
+	[RST_VE]		=  { 0x13c, BIT(0) },
+
+	[RST_GPU]		=  { 0x154, BIT(30) },
+
+	[RST_IEP]		=  { 0x160, BIT(30) },
+};
+
+static const struct sunxi_ccu_desc sun5i_gr8_ccu_desc = {
+	.ccu_clks	= sun5i_gr8_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun5i_gr8_ccu_clks),
+
+	.hw_clks	= &sun5i_gr8_hw_clks,
+
+	.resets		= sun5i_gr8_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun5i_gr8_ccu_resets),
+};
+
+static void __init sun5i_gr8_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	/* Force the PLL-Audio-1x divider to 4 */
+	val = readl(reg + SUN5I_PLL_AUDIO_REG);
+	val &= ~GENMASK(19, 16);
+	writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
+
+	/*
+	 * Use the peripheral PLL as the AHB parent, instead of CPU /
+	 * AXI which have rate changes due to cpufreq.
+	 *
+	 * This is especially a big deal for the HS timer whose parent
+	 * clock is AHB.
+	 */
+	val = readl(reg + SUN5I_AHB_REG);
+	val &= ~GENMASK(7, 6);
+	writel(val | (2 << 6), reg + SUN5I_AHB_REG);
+
+	sunxi_ccu_probe(node, reg, &sun5i_gr8_ccu_desc);
+}
+CLK_OF_DECLARE(sun5i_gr8_ccu, "nextthing,gr8-ccu",
+	       sun5i_gr8_ccu_setup);
-- 
git-series 0.8.11

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

* [PATCH 9/10] ARM: sun5i: Convert to CCU
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (7 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 8/10] clk: sunxi-ng: Add GR8 driver Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-13 15:01   ` Chen-Yu Tsai
  2016-11-08 17:23 ` [PATCH 10/10] ARM: gr8: " Maxime Ripard
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Now that we have drivers for all of them, convert all the SoCs that share
the sun5i DTSI to the new CCU driver.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun5i-a10s.dtsi |  94 +-------
 arch/arm/boot/dts/sun5i-a13.dtsi  | 140 +-----------
 arch/arm/boot/dts/sun5i-r8.dtsi   |  10 +-
 arch/arm/boot/dts/sun5i.dtsi      | 368 ++++---------------------------
 4 files changed, 90 insertions(+), 522 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 7aa8c7aa0153..1d26ae7267dc 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -61,99 +61,33 @@
 		#size-cells = <1>;
 		ranges;
 
-		framebuffer@0 {
-			compatible = "allwinner,simple-framebuffer",
-				     "simple-framebuffer";
-			allwinner,pipeline = "de_be0-lcd0-hdmi";
-			clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
-				 <&ahb_gates 43>, <&ahb_gates 44>;
-			status = "disabled";
-		};
-
 		framebuffer@1 {
 			compatible = "allwinner,simple-framebuffer",
 				     "simple-framebuffer";
-			allwinner,pipeline = "de_be0-lcd0";
-			clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
-				 <&ahb_gates 44>;
+			allwinner,pipeline = "de_be0-lcd0-tve0";
+			clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
+				 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
 			status = "disabled";
 		};
 
 		framebuffer@2 {
 			compatible = "allwinner,simple-framebuffer",
 				     "simple-framebuffer";
-			allwinner,pipeline = "de_be0-lcd0-tve0";
-			clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>,
-				 <&ahb_gates 36>, <&ahb_gates 44>;
+			allwinner,pipeline = "de_be0-lcd0-hdmi";
+			clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_HDMI>,
+				 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DRAM_DE_BE>,
+				 <&ccu CLK_DE_BE>, <&ccu CLK_HDMI>;
 			status = "disabled";
 		};
 	};
 
-	clocks {
-		ahb_gates: clk@01c20060 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
-			reg = <0x01c20060 0x8>;
-			clocks = <&ahb>;
-			clock-indices = <0>, <1>,
-					<2>, <5>, <6>,
-					<7>, <8>, <9>,
-					<10>, <13>,
-					<14>, <17>, <18>,
-					<20>, <21>, <22>,
-					<26>, <28>, <32>,
-					<34>, <36>, <40>,
-					<43>, <44>,
-					<46>, <51>,
-					<52>;
-			clock-output-names = "ahb_usbotg", "ahb_ehci",
-					     "ahb_ohci", "ahb_ss", "ahb_dma",
-					     "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-					     "ahb_mmc2", "ahb_nand",
-					     "ahb_sdram", "ahb_emac", "ahb_ts",
-					     "ahb_spi0", "ahb_spi1", "ahb_spi2",
-					     "ahb_gps", "ahb_stimer", "ahb_ve",
-					     "ahb_tve", "ahb_lcd", "ahb_csi",
-					     "ahb_hdmi", "ahb_de_be",
-					     "ahb_de_fe", "ahb_iep",
-					     "ahb_mali400";
-		};
-
-		apb0_gates: clk@01c20068 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
-			reg = <0x01c20068 0x4>;
-			clocks = <&apb0>;
-			clock-indices = <0>, <3>,
-					<5>, <6>,
-					<10>;
-			clock-output-names = "apb0_codec", "apb0_iis",
-					     "apb0_pio", "apb0_ir",
-					     "apb0_keypad";
-		};
-
-		apb1_gates: clk@01c2006c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
-			reg = <0x01c2006c 0x4>;
-			clocks = <&apb1>;
-			clock-indices = <0>, <1>,
-					<2>, <16>,
-					<17>, <18>,
-					<19>;
-			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-					     "apb1_i2c2", "apb1_uart0",
-					     "apb1_uart1", "apb1_uart2",
-					     "apb1_uart3";
-		};
-	};
-
 	soc@01c00000 {
 		emac: ethernet@01c0b000 {
 			compatible = "allwinner,sun4i-a10-emac";
 			reg = <0x01c0b000 0x1000>;
 			interrupts = <55>;
-			clocks = <&ahb_gates 17>;
+			clocks = <&ccu CLK_AHB_EMAC>;
 			allwinner,sram = <&emac_sram 1>;
 			status = "disabled";
 		};
@@ -169,7 +103,7 @@
 		pwm: pwm@01c20e00 {
 			compatible = "allwinner,sun5i-a10s-pwm";
 			reg = <0x01c20e00 0xc>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_HOSC>;
 			#pwm-cells = <3>;
 			status = "disabled";
 		};
@@ -180,7 +114,7 @@
 			interrupts = <1>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 16>;
+			clocks = <&ccu CLK_APB1_UART0>;
 			status = "disabled";
 		};
 
@@ -190,12 +124,16 @@
 			interrupts = <3>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 18>;
+			clocks = <&ccu CLK_APB1_UART2>;
 			status = "disabled";
 		};
 	};
 };
 
+&ccu {
+	compatible = "allwinner,sun5i-a10s-ccu";
+};
+
 &pio {
 	compatible = "allwinner,sun5i-a10s-pinctrl";
 
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index a17ba0243db3..0330304f1d42 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -61,8 +61,8 @@
 			compatible = "allwinner,simple-framebuffer",
 				     "simple-framebuffer";
 			allwinner,pipeline = "de_be0-lcd0";
-			clocks = <&ahb_gates 36>, <&ahb_gates 44>, <&de_be_clk>,
-				 <&tcon_ch0_clk>, <&dram_gates 26>;
+			clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
 			status = "disabled";
 		};
 	};
@@ -99,114 +99,6 @@
 		};
 	};
 
-	clocks {
-		ahb_gates: clk@01c20060 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-ahb-gates-clk";
-			reg = <0x01c20060 0x8>;
-			clocks = <&ahb>;
-			clock-indices = <0>, <1>,
-					<2>, <5>, <6>,
-					<7>, <8>, <9>,
-					<10>, <13>,
-					<14>, <20>,
-					<21>, <22>,
-					<28>, <32>, <34>,
-					<36>, <40>, <44>,
-					<46>, <51>,
-					<52>;
-			clock-output-names = "ahb_usbotg", "ahb_ehci",
-					     "ahb_ohci", "ahb_ss", "ahb_dma",
-					     "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-					     "ahb_mmc2", "ahb_nand",
-					     "ahb_sdram", "ahb_spi0",
-					     "ahb_spi1", "ahb_spi2",
-					     "ahb_stimer", "ahb_ve", "ahb_tve",
-					     "ahb_lcd", "ahb_csi", "ahb_de_be",
-					     "ahb_de_fe", "ahb_iep",
-					     "ahb_mali400";
-		};
-
-		apb0_gates: clk@01c20068 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-apb0-gates-clk";
-			reg = <0x01c20068 0x4>;
-			clocks = <&apb0>;
-			clock-indices = <0>, <5>,
-					<6>;
-			clock-output-names = "apb0_codec", "apb0_pio",
-					     "apb0_ir";
-		};
-
-		apb1_gates: clk@01c2006c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-apb1-gates-clk";
-			reg = <0x01c2006c 0x4>;
-			clocks = <&apb1>;
-			clock-indices = <0>, <1>,
-					<2>, <17>,
-					<19>;
-			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-					     "apb1_i2c2", "apb1_uart1",
-					     "apb1_uart3";
-		};
-
-		dram_gates: clk@01c20100 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-dram-gates-clk",
-				     "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c20100 0x4>;
-			clocks = <&pll5 0>;
-			clock-indices = <0>,
-					<1>,
-					<25>,
-					<26>,
-					<29>,
-					<31>;
-			clock-output-names = "dram_ve",
-					     "dram_csi",
-					     "dram_de_fe",
-					     "dram_de_be",
-					     "dram_ace",
-					     "dram_iep";
-		};
-
-		de_be_clk: clk@01c20104 {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c20104 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-be";
-		};
-
-		de_fe_clk: clk@01c2010c {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c2010c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-fe";
-		};
-
-		tcon_ch0_clk: clk@01c20118 {
-			#clock-cells = <0>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
-			reg = <0x01c20118 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch0-sclk";
-		};
-
-		tcon_ch1_clk: clk@01c2012c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
-			reg = <0x01c2012c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch1-sclk";
-		};
-	};
-
 	display-engine {
 		compatible = "allwinner,sun5i-a13-display-engine";
 		allwinner,pipelines = <&fe0>;
@@ -217,11 +109,11 @@
 			compatible = "allwinner,sun5i-a13-tcon";
 			reg = <0x01c0c000 0x1000>;
 			interrupts = <44>;
-			resets = <&tcon_ch0_clk 1>;
+			resets = <&ccu RST_LCD>;
 			reset-names = "lcd";
-			clocks = <&ahb_gates 36>,
-				 <&tcon_ch0_clk>,
-				 <&tcon_ch1_clk>;
+			clocks = <&ccu CLK_AHB_LCD>,
+				 <&ccu CLK_TCON_CH0>,
+				 <&ccu CLK_TCON_CH1>;
 			clock-names = "ahb",
 				      "tcon-ch0",
 				      "tcon-ch1";
@@ -254,7 +146,7 @@
 		pwm: pwm@01c20e00 {
 			compatible = "allwinner,sun5i-a13-pwm";
 			reg = <0x01c20e00 0xc>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_HOSC>;
 			#pwm-cells = <3>;
 			status = "disabled";
 		};
@@ -263,11 +155,11 @@
 			compatible = "allwinner,sun5i-a13-display-frontend";
 			reg = <0x01e00000 0x20000>;
 			interrupts = <47>;
-			clocks = <&ahb_gates 46>, <&de_fe_clk>,
-				 <&dram_gates 25>;
+			clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>,
+				 <&ccu CLK_DRAM_DE_FE>;
 			clock-names = "ahb", "mod",
 				      "ram";
-			resets = <&de_fe_clk>;
+			resets = <&ccu RST_DE_FE>;
 			status = "disabled";
 
 			ports {
@@ -290,14 +182,14 @@
 		be0: display-backend@01e60000 {
 			compatible = "allwinner,sun5i-a13-display-backend";
 			reg = <0x01e60000 0x10000>;
-			clocks = <&ahb_gates 44>, <&de_be_clk>,
-				 <&dram_gates 26>;
+			clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_DRAM_DE_BE>;
 			clock-names = "ahb", "mod",
 				      "ram";
-			resets = <&de_be_clk>;
+			resets = <&ccu RST_DE_BE>;
 			status = "disabled";
 
-			assigned-clocks = <&de_be_clk>;
+			assigned-clocks = <&ccu CLK_DE_BE>;
 			assigned-clock-rates = <300000000>;
 
 			ports {
@@ -330,6 +222,10 @@
 	};
 };
 
+&ccu {
+	compatible = "allwinner,sun5i-a13-ccu";
+};
+
 &cpu0 {
 	clock-latency = <244144>; /* 8 32k periods */
 	operating-points = <
diff --git a/arch/arm/boot/dts/sun5i-r8.dtsi b/arch/arm/boot/dts/sun5i-r8.dtsi
index 8b058f53b7dc..4c1141396c99 100644
--- a/arch/arm/boot/dts/sun5i-r8.dtsi
+++ b/arch/arm/boot/dts/sun5i-r8.dtsi
@@ -51,9 +51,9 @@
 			compatible = "allwinner,simple-framebuffer",
 				     "simple-framebuffer";
 			allwinner,pipeline = "de_be0-lcd0-tve0";
-			clocks = <&ahb_gates 34>, <&ahb_gates 36>,
-				 <&ahb_gates 44>, <&de_be_clk>,
-				 <&tcon_ch1_clk>, <&dram_gates 26>;
+			clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
+				 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
 			status = "disabled";
 		};
 	};
@@ -62,8 +62,8 @@
 		tve0: tv-encoder@01c0a000 {
 			compatible = "allwinner,sun4i-a10-tv-encoder";
 			reg = <0x01c0a000 0x1000>;
-			clocks = <&ahb_gates 34>;
-			resets = <&tcon_ch0_clk 0>;
+			clocks = <&ccu CLK_AHB_TVE>;
+			resets = <&ccu RST_TVE>;
 			status = "disabled";
 
 			port {
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index b4ccee8cfb02..2dbc7623ec04 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -44,13 +44,29 @@
 
 #include "skeleton.dtsi"
 
-#include <dt-bindings/clock/sun4i-a10-pll2.h>
+#include <dt-bindings/clock/sun5i-ccu.h>
 #include <dt-bindings/dma/sun4i-a10.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/reset/sun5i-ccu.h>
 
 / {
 	interrupt-parent = <&intc>;
 
+	chosen {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		framebuffer@0 {
+			compatible = "allwinner,simple-framebuffer",
+				     "simple-framebuffer";
+			allwinner,pipeline = "de_be0-lcd0";
+			clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
+			status = "disabled";
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -59,7 +75,7 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a8";
 			reg = <0x0>;
-			clocks = <&cpu>;
+			clocks = <&ccu CLK_CPU>;
 		};
 	};
 
@@ -68,291 +84,19 @@
 		#size-cells = <1>;
 		ranges;
 
-		/*
-		 * This is a dummy clock, to be used as placeholder on
-		 * other mux clocks when a specific parent clock is not
-		 * yet implemented. It should be dropped when the driver
-		 * is complete.
-		 */
-		dummy: dummy {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
 		osc24M: clk@01c20050 {
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-osc-clk";
-			reg = <0x01c20050 0x4>;
+			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
 			clock-output-names = "osc24M";
 		};
 
-		osc3M: osc3M_clk {
-			compatible = "fixed-factor-clock";
-			#clock-cells = <0>;
-			clock-div = <8>;
-			clock-mult = <1>;
-			clocks = <&osc24M>;
-			clock-output-names = "osc3M";
-		};
-
 		osc32k: clk@0 {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
 			clock-output-names = "osc32k";
 		};
-
-		pll1: clk@01c20000 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20000 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll1";
-		};
-
-		pll2: clk@01c20008 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-pll2-clk";
-			reg = <0x01c20008 0x8>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll2-1x", "pll2-2x",
-					     "pll2-4x", "pll2-8x";
-		};
-
-		pll3: clk@01c20010 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20010 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll3";
-		};
-
-		pll3x2: pll3x2_clk {
-			compatible = "allwinner,sun4i-a10-pll3-2x-clk", "fixed-factor-clock";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll3>;
-			clock-output-names = "pll3-2x";
-		};
-
-		pll4: clk@01c20018 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20018 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll4";
-		};
-
-		pll5: clk@01c20020 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll5-clk";
-			reg = <0x01c20020 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll5_ddr", "pll5_other";
-		};
-
-		pll6: clk@01c20028 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll6-clk";
-			reg = <0x01c20028 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll6_sata", "pll6_other", "pll6";
-		};
-
-		pll7: clk@01c20030 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20030 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll7";
-		};
-
-		pll7x2: pll7x2_clk {
-			compatible = "fixed-factor-clock";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll7>;
-			clock-output-names = "pll7-2x";
-		};
-
-		/* dummy is 200M */
-		cpu: cpu@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-cpu-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
-			clock-output-names = "cpu";
-		};
-
-		axi: axi@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-axi-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&cpu>;
-			clock-output-names = "axi";
-		};
-
-		ahb: ahb@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-ahb-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&axi>, <&cpu>, <&pll6 1>;
-			clock-output-names = "ahb";
-			/*
-			 * Use PLL6 as parent, instead of CPU/AXI
-			 * which has rate changes due to cpufreq
-			 */
-			assigned-clocks = <&ahb>;
-			assigned-clock-parents = <&pll6 1>;
-		};
-
-		apb0: apb0@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb0-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&ahb>;
-			clock-output-names = "apb0";
-		};
-
-		apb1: clk@01c20058 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb1-clk";
-			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
-			clock-output-names = "apb1";
-		};
-
-		axi_gates: clk@01c2005c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-axi-gates-clk";
-			reg = <0x01c2005c 0x4>;
-			clocks = <&axi>;
-			clock-indices = <0>;
-			clock-output-names = "axi_dram";
-		};
-
-		nand_clk: clk@01c20080 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20080 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "nand";
-		};
-
-		ms_clk: clk@01c20084 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20084 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ms";
-		};
-
-		mmc0_clk: clk@01c20088 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20088 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0",
-					     "mmc0_output",
-					     "mmc0_sample";
-		};
-
-		mmc1_clk: clk@01c2008c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c2008c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1",
-					     "mmc1_output",
-					     "mmc1_sample";
-		};
-
-		mmc2_clk: clk@01c20090 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20090 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2",
-					     "mmc2_output",
-					     "mmc2_sample";
-		};
-
-		ts_clk: clk@01c20098 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20098 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ts";
-		};
-
-		ss_clk: clk@01c2009c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c2009c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ss";
-		};
-
-		spi0_clk: clk@01c200a0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi0";
-		};
-
-		spi1_clk: clk@01c200a4 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a4 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi1";
-		};
-
-		spi2_clk: clk@01c200a8 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a8 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi2";
-		};
-
-		ir0_clk: clk@01c200b0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200b0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ir0";
-		};
-
-		usb_clk: clk@01c200cc {
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun5i-a13-usb-clk";
-			reg = <0x01c200cc 0x4>;
-			clocks = <&pll6 1>;
-			clock-output-names = "usb_ohci0", "usb_phy";
-		};
-
-		codec_clk: clk@01c20140 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-codec-clk";
-			reg = <0x01c20140 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "codec";
-		};
-
-		mbus_clk: clk@01c2015c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-mbus-clk";
-			reg = <0x01c2015c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mbus";
-		};
 	};
 
 	soc@01c00000 {
@@ -395,7 +139,7 @@
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
 			interrupts = <27>;
-			clocks = <&ahb_gates 6>;
+			clocks = <&ccu CLK_AHB_DMA>;
 			#dma-cells = <2>;
 		};
 
@@ -403,7 +147,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c05000 0x1000>;
 			interrupts = <10>;
-			clocks = <&ahb_gates 20>, <&spi0_clk>;
+			clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 			       <&dma SUN4I_DMA_DEDICATED 26>;
@@ -417,7 +161,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c06000 0x1000>;
 			interrupts = <11>;
-			clocks = <&ahb_gates 21>, <&spi1_clk>;
+			clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 			       <&dma SUN4I_DMA_DEDICATED 8>;
@@ -430,14 +174,8 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>,
-				 <&mmc0_clk 0>,
-				 <&mmc0_clk 1>,
-				 <&mmc0_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
 			interrupts = <32>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -447,14 +185,8 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>,
-				 <&mmc1_clk 0>,
-				 <&mmc1_clk 1>,
-				 <&mmc1_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
 			interrupts = <33>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -464,14 +196,8 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>,
-				 <&mmc2_clk 0>,
-				 <&mmc2_clk 1>,
-				 <&mmc2_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
+			clock-names = "ahb", "mmc";
 			interrupts = <34>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -481,7 +207,7 @@
 		usb_otg: usb@01c13000 {
 			compatible = "allwinner,sun4i-a10-musb";
 			reg = <0x01c13000 0x0400>;
-			clocks = <&ahb_gates 0>;
+			clocks = <&ccu CLK_AHB_OTG>;
 			interrupts = <38>;
 			interrupt-names = "mc";
 			phys = <&usbphy 0>;
@@ -496,9 +222,9 @@
 			compatible = "allwinner,sun5i-a13-usb-phy";
 			reg = <0x01c13400 0x10 0x01c14800 0x4>;
 			reg-names = "phy_ctrl", "pmu1";
-			clocks = <&usb_clk 8>;
+			clocks = <&ccu CLK_USB_PHY0>;
 			clock-names = "usb_phy";
-			resets = <&usb_clk 0>, <&usb_clk 1>;
+			resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
 			reset-names = "usb0_reset", "usb1_reset";
 			status = "disabled";
 		};
@@ -507,7 +233,7 @@
 			compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
 			reg = <0x01c14000 0x100>;
 			interrupts = <39>;
-			clocks = <&ahb_gates 1>;
+			clocks = <&ccu CLK_AHB_EHCI>;
 			phys = <&usbphy 1>;
 			phy-names = "usb";
 			status = "disabled";
@@ -517,7 +243,7 @@
 			compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
 			reg = <0x01c14400 0x100>;
 			interrupts = <40>;
-			clocks = <&usb_clk 6>, <&ahb_gates 2>;
+			clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
 			phys = <&usbphy 1>;
 			phy-names = "usb";
 			status = "disabled";
@@ -527,7 +253,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c17000 0x1000>;
 			interrupts = <12>;
-			clocks = <&ahb_gates 22>, <&spi2_clk>;
+			clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 			       <&dma SUN4I_DMA_DEDICATED 28>;
@@ -537,6 +263,14 @@
 			#size-cells = <0>;
 		};
 
+		ccu: clock@01c20000 {
+			reg = <0x01c20000 0x400>;
+			clocks = <&osc24M>, <&osc32k>;
+			clock-names = "hosc", "losc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
 		intc: interrupt-controller@01c20400 {
 			compatible = "allwinner,sun4i-a10-ic";
 			reg = <0x01c20400 0x400>;
@@ -547,7 +281,7 @@
 		pio: pinctrl@01c20800 {
 			reg = <0x01c20800 0x400>;
 			interrupts = <28>;
-			clocks = <&apb0_gates 5>;
+			clocks = <&ccu CLK_APB0_PIO>;
 			gpio-controller;
 			interrupt-controller;
 			#interrupt-cells = <3>;
@@ -641,7 +375,7 @@
 			compatible = "allwinner,sun4i-a10-timer";
 			reg = <0x01c20c00 0x90>;
 			interrupts = <22>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_HOSC>;
 		};
 
 		wdt: watchdog@01c20c90 {
@@ -661,7 +395,7 @@
 			compatible = "allwinner,sun4i-a10-codec";
 			reg = <0x01c22c00 0x40>;
 			interrupts = <30>;
-			clocks = <&apb0_gates 0>, <&codec_clk>;
+			clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
 			clock-names = "apb", "codec";
 			dmas = <&dma SUN4I_DMA_NORMAL 19>,
 			       <&dma SUN4I_DMA_NORMAL 19>;
@@ -687,7 +421,7 @@
 			interrupts = <2>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 17>;
+			clocks = <&ccu CLK_APB1_UART1>;
 			status = "disabled";
 		};
 
@@ -697,7 +431,7 @@
 			interrupts = <4>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 19>;
+			clocks = <&ccu CLK_APB1_UART3>;
 			status = "disabled";
 		};
 
@@ -705,7 +439,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2ac00 0x400>;
 			interrupts = <7>;
-			clocks = <&apb1_gates 0>;
+			clocks = <&ccu CLK_APB1_I2C0>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -715,7 +449,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2b000 0x400>;
 			interrupts = <8>;
-			clocks = <&apb1_gates 1>;
+			clocks = <&ccu CLK_APB1_I2C1>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -725,7 +459,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2b400 0x400>;
 			interrupts = <9>;
-			clocks = <&apb1_gates 2>;
+			clocks = <&ccu CLK_APB1_I2C2>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -735,7 +469,7 @@
 			compatible = "allwinner,sun5i-a13-hstimer";
 			reg = <0x01c60000 0x1000>;
 			interrupts = <82>, <83>;
-			clocks = <&ahb_gates 28>;
+			clocks = <&ccu CLK_AHB_HSTIMER>;
 		};
 	};
 };
-- 
git-series 0.8.11

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

* [PATCH 10/10] ARM: gr8: Convert to CCU
  2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
                   ` (8 preceding siblings ...)
  2016-11-08 17:23 ` [PATCH 9/10] ARM: sun5i: Convert to CCU Maxime Ripard
@ 2016-11-08 17:23 ` Maxime Ripard
  2016-11-12 23:51   ` kbuild test robot
  9 siblings, 1 reply; 23+ messages in thread
From: Maxime Ripard @ 2016-11-08 17:23 UTC (permalink / raw)
  To: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, Maxime Ripard
  Cc: linux-arm-kernel, linux-kernel, linux-clk

Now that we have a driver for the GR8, we can convert our DT to it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/ntc-gr8.dtsi | 518 +++-------------------------------
 1 file changed, 55 insertions(+), 463 deletions(-)

diff --git a/arch/arm/boot/dts/ntc-gr8.dtsi b/arch/arm/boot/dts/ntc-gr8.dtsi
index ea86d4d58db6..b18f35c144d7 100644
--- a/arch/arm/boot/dts/ntc-gr8.dtsi
+++ b/arch/arm/boot/dts/ntc-gr8.dtsi
@@ -42,9 +42,10 @@
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include <dt-bindings/clock/sun4i-a10-pll2.h>
+#include <dt-bindings/clock/sun5i-ccu.h>
 #include <dt-bindings/dma/sun4i-a10.h>
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/reset/sun5i-ccu.h>
 
 / {
 	interrupt-parent = <&intc>;
@@ -59,7 +60,7 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a8";
 			reg = <0x0>;
-			clocks = <&cpu>;
+			clocks = <&ccu CLK_CPU>;
 		};
 	};
 
@@ -68,419 +69,19 @@
 		#size-cells = <1>;
 		ranges;
 
-		/*
-		 * This is a dummy clock, to be used as placeholder on
-		 * other mux clocks when a specific parent clock is not
-		 * yet implemented. It should be dropped when the driver
-		 * is complete.
-		 */
-		dummy: dummy {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
 		osc24M: clk@01c20050 {
 			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-osc-clk";
-			reg = <0x01c20050 0x4>;
+			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
 			clock-output-names = "osc24M";
 		};
 
-		osc3M: osc3M-clk {
-			compatible = "fixed-factor-clock";
-			#clock-cells = <0>;
-			clock-div = <8>;
-			clock-mult = <1>;
-			clocks = <&osc24M>;
-			clock-output-names = "osc3M";
-		};
-
 		osc32k: clk@0 {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
 			clock-output-names = "osc32k";
 		};
-
-		pll1: clk@01c20000 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20000 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll1";
-		};
-
-		pll2: clk@01c20008 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-pll2-clk";
-			reg = <0x01c20008 0x8>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll2-1x", "pll2-2x",
-					     "pll2-4x", "pll2-8x";
-		};
-
-		pll3: clk@01c20010 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20010 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll3";
-		};
-
-		pll3x2: pll3x2-clk {
-			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll3>;
-			clock-output-names = "pll3-2x";
-		};
-
-		pll4: clk@01c20018 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20018 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll4";
-		};
-
-		pll5: clk@01c20020 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll5-clk";
-			reg = <0x01c20020 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll5_ddr", "pll5_other";
-		};
-
-		pll6: clk@01c20028 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll6-clk";
-			reg = <0x01c20028 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll6_sata", "pll6_other", "pll6";
-		};
-
-		pll7: clk@01c20030 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20030 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll7";
-		};
-
-		pll7x2: pll7x2-clk {
-			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll7>;
-			clock-output-names = "pll7-2x";
-		};
-
-		/* dummy is 200M */
-		cpu: cpu@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-cpu-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
-			clock-output-names = "cpu";
-		};
-
-		axi: axi@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-axi-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&cpu>;
-			clock-output-names = "axi";
-		};
-
-		ahb: ahb@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-ahb-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&axi>, <&cpu>, <&pll6 1>;
-			clock-output-names = "ahb";
-			/*
-			 * Use PLL6 as parent, instead of CPU/AXI
-			 * which has rate changes due to cpufreq
-			 */
-			assigned-clocks = <&ahb>;
-			assigned-clock-parents = <&pll6 1>;
-		};
-
-		apb0: apb0@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb0-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&ahb>;
-			clock-output-names = "apb0";
-		};
-
-		apb1: clk@01c20058 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb1-clk";
-			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
-			clock-output-names = "apb1";
-		};
-
-		axi_gates: clk@01c2005c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c2005c 0x4>;
-			clocks = <&axi>;
-			clock-indices = <0>;
-			clock-output-names = "axi_dram";
-		};
-
-		ahb_gates: clk@01c20060 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-ahb-gates-clk";
-			reg = <0x01c20060 0x8>;
-			clocks = <&ahb>;
-			clock-indices = <0>, <1>,
-					<2>, <5>, <6>,
-					<7>, <8>, <9>,
-					<10>, <13>,
-					<14>, <17>, <20>,
-					<21>, <22>,
-					<28>, <32>, <34>,
-					<36>, <40>, <44>,
-					<46>, <51>,
-					<52>;
-			clock-output-names = "ahb_usbotg", "ahb_ehci",
-					     "ahb_ohci", "ahb_ss", "ahb_dma",
-					     "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-					     "ahb_mmc2", "ahb_nand",
-					     "ahb_sdram", "ahb_emac", "ahb_spi0",
-					     "ahb_spi1", "ahb_spi2",
-					     "ahb_hstimer", "ahb_ve", "ahb_tve",
-					     "ahb_lcd", "ahb_csi", "ahb_de_be",
-					     "ahb_de_fe", "ahb_iep",
-					     "ahb_mali400";
-		};
-
-		apb0_gates: clk@01c20068 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c20068 0x4>;
-			clocks = <&apb0>;
-			clock-indices = <0>, <3>,
-					<5>, <6>;
-			clock-output-names = "apb0_codec", "apb0_i2s0",
-					     "apb0_pio", "apb0_ir";
-		};
-
-		apb1_gates: clk@01c2006c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c2006c 0x4>;
-			clocks = <&apb1>;
-			clock-indices = <0>, <1>,
-					<2>, <17>,
-					<18>, <19>;
-			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-					     "apb1_i2c2", "apb1_uart1",
-					     "apb1_uart2", "apb1_uart3";
-		};
-
-		nand_clk: clk@01c20080 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20080 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "nand";
-		};
-
-		ms_clk: clk@01c20084 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20084 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ms";
-		};
-
-		mmc0_clk: clk@01c20088 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20088 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0",
-					     "mmc0_output",
-					     "mmc0_sample";
-		};
-
-		mmc1_clk: clk@01c2008c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c2008c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1",
-					     "mmc1_output",
-					     "mmc1_sample";
-		};
-
-		mmc2_clk: clk@01c20090 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20090 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2",
-					     "mmc2_output",
-					     "mmc2_sample";
-		};
-
-		ts_clk: clk@01c20098 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20098 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ts";
-		};
-
-		ss_clk: clk@01c2009c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c2009c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ss";
-		};
-
-		spi0_clk: clk@01c200a0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi0";
-		};
-
-		spi1_clk: clk@01c200a4 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a4 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi1";
-		};
-
-		spi2_clk: clk@01c200a8 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a8 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi2";
-		};
-
-		ir0_clk: clk@01c200b0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200b0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ir0";
-		};
-
-		i2s0_clk: clk@01c200b8 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod1-clk";
-			reg = <0x01c200b8 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-				 <&pll2 SUN4I_A10_PLL2_4X>,
-				 <&pll2 SUN4I_A10_PLL2_2X>,
-				 <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "i2s0";
-		};
-
-		spdif_clk: clk@01c200c0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod1-clk";
-			reg = <0x01c200c0 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-				 <&pll2 SUN4I_A10_PLL2_4X>,
-				 <&pll2 SUN4I_A10_PLL2_2X>,
-				 <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "spdif";
-		};
-
-		usb_clk: clk@01c200cc {
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun5i-a13-usb-clk";
-			reg = <0x01c200cc 0x4>;
-			clocks = <&pll6 1>;
-			clock-output-names = "usb_ohci0", "usb_phy";
-		};
-
-		dram_gates: clk@01c20100 {
-			#clock-cells = <1>;
-			compatible = "nextthing,gr8-dram-gates-clk",
-				     "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c20100 0x4>;
-			clocks = <&pll5 0>;
-			clock-indices = <0>,
-					<1>,
-					<25>,
-					<26>,
-					<29>,
-					<31>;
-			clock-output-names = "dram_ve",
-					     "dram_csi",
-					     "dram_de_fe",
-					     "dram_de_be",
-					     "dram_ace",
-					     "dram_iep";
-		};
-
-		de_be_clk: clk@01c20104 {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c20104 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-be";
-		};
-
-		de_fe_clk: clk@01c2010c {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c2010c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-fe";
-		};
-
-		tcon_ch0_clk: clk@01c20118 {
-			#clock-cells = <0>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
-			reg = <0x01c20118 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch0-sclk";
-		};
-
-		tcon_ch1_clk: clk@01c2012c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
-			reg = <0x01c2012c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch1-sclk";
-		};
-
-		codec_clk: clk@01c20140 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-codec-clk";
-			reg = <0x01c20140 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "codec";
-		};
-
-		mbus_clk: clk@01c2015c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-mbus-clk";
-			reg = <0x01c2015c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mbus";
-		};
 	};
 
 	display-engine {
@@ -528,7 +129,7 @@
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
 			interrupts = <27>;
-			clocks = <&ahb_gates 6>;
+			clocks = <&ccu CLK_AHB_DMA>;
 			#dma-cells = <2>;
 		};
 
@@ -536,7 +137,7 @@
 			compatible = "allwinner,sun4i-a10-nand";
 			reg = <0x01c03000 0x1000>;
 			interrupts = <37>;
-			clocks = <&ahb_gates 13>, <&nand_clk>;
+			clocks = <&ccu CLK_AHB_NAND>, <&ccu CLK_NAND>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 3>;
 			dma-names = "rxtx";
@@ -549,7 +150,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c05000 0x1000>;
 			interrupts = <10>;
-			clocks = <&ahb_gates 20>, <&spi0_clk>;
+			clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 27>,
 			       <&dma SUN4I_DMA_DEDICATED 26>;
@@ -563,7 +164,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c06000 0x1000>;
 			interrupts = <11>;
-			clocks = <&ahb_gates 21>, <&spi1_clk>;
+			clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 9>,
 			       <&dma SUN4I_DMA_DEDICATED 8>;
@@ -576,8 +177,8 @@
 		tve0: tv-encoder@01c0a000 {
 			compatible = "allwinner,sun4i-a10-tv-encoder";
 			reg = <0x01c0a000 0x1000>;
-			clocks = <&ahb_gates 34>;
-			resets = <&tcon_ch0_clk 0>;
+			clocks = <&ccu CLK_AHB_TVE>;
+			resets = <&ccu RST_TVE>;
 			status = "disabled";
 
 			port {
@@ -595,11 +196,11 @@
 			compatible = "allwinner,sun5i-a13-tcon";
 			reg = <0x01c0c000 0x1000>;
 			interrupts = <44>;
-			resets = <&tcon_ch0_clk 1>;
+			resets = <&ccu RST_LCD>;
 			reset-names = "lcd";
-			clocks = <&ahb_gates 36>,
-				 <&tcon_ch0_clk>,
-				 <&tcon_ch1_clk>;
+			clocks = <&ccu CLK_AHB_LCD>,
+				 <&ccu CLK_TCON_CH0>,
+				 <&ccu CLK_TCON_CH1>;
 			clock-names = "ahb",
 				      "tcon-ch0",
 				      "tcon-ch1";
@@ -637,14 +238,8 @@
 		mmc0: mmc@01c0f000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>,
-				 <&mmc0_clk 0>,
-				 <&mmc0_clk 1>,
-				 <&mmc0_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
 			interrupts = <32>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -654,14 +249,8 @@
 		mmc1: mmc@01c10000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>,
-				 <&mmc1_clk 0>,
-				 <&mmc1_clk 1>,
-				 <&mmc1_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
 			interrupts = <33>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -671,14 +260,8 @@
 		mmc2: mmc@01c11000 {
 			compatible = "allwinner,sun5i-a13-mmc";
 			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>,
-				 <&mmc2_clk 0>,
-				 <&mmc2_clk 1>,
-				 <&mmc2_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
+			clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
+			clock-names = "ahb", "mmc";
 			interrupts = <34>;
 			status = "disabled";
 			#address-cells = <1>;
@@ -688,7 +271,7 @@
 		usb_otg: usb@01c13000 {
 			compatible = "allwinner,sun4i-a10-musb";
 			reg = <0x01c13000 0x0400>;
-			clocks = <&ahb_gates 0>;
+			clocks = <&ccu CLK_AHB_OTG>;
 			interrupts = <38>;
 			interrupt-names = "mc";
 			phys = <&usbphy 0>;
@@ -705,9 +288,9 @@
 			compatible = "allwinner,sun5i-a13-usb-phy";
 			reg = <0x01c13400 0x10 0x01c14800 0x4>;
 			reg-names = "phy_ctrl", "pmu1";
-			clocks = <&usb_clk 8>;
+			clocks = <&ccu CLK_USB_PHY0>;
 			clock-names = "usb_phy";
-			resets = <&usb_clk 0>, <&usb_clk 1>;
+			resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
 			reset-names = "usb0_reset", "usb1_reset";
 			status = "disabled";
 		};
@@ -716,7 +299,7 @@
 			compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
 			reg = <0x01c14000 0x100>;
 			interrupts = <39>;
-			clocks = <&ahb_gates 1>;
+			clocks = <&ccu CLK_AHB_EHCI>;
 			phys = <&usbphy 1>;
 			phy-names = "usb";
 			status = "disabled";
@@ -726,7 +309,7 @@
 			compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
 			reg = <0x01c14400 0x100>;
 			interrupts = <40>;
-			clocks = <&usb_clk 6>, <&ahb_gates 2>;
+			clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
 			phys = <&usbphy 1>;
 			phy-names = "usb";
 			status = "disabled";
@@ -736,7 +319,7 @@
 			compatible = "allwinner,sun4i-a10-spi";
 			reg = <0x01c17000 0x1000>;
 			interrupts = <12>;
-			clocks = <&ahb_gates 22>, <&spi2_clk>;
+			clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
 			clock-names = "ahb", "mod";
 			dmas = <&dma SUN4I_DMA_DEDICATED 29>,
 			       <&dma SUN4I_DMA_DEDICATED 28>;
@@ -746,6 +329,15 @@
 			#size-cells = <0>;
 		};
 
+		ccu: clock@01c20000 {
+			compatible = "nextthing,gr8-ccu";
+			reg = <0x01c20000 0x400>;
+			clocks = <&osc24M>, <&osc32k>;
+			clock-names = "hosc", "losc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
 		intc: interrupt-controller@01c20400 {
 			compatible = "allwinner,sun4i-a10-ic";
 			reg = <0x01c20400 0x400>;
@@ -757,7 +349,7 @@
 			compatible = "nextthing,gr8-pinctrl";
 			reg = <0x01c20800 0x400>;
 			interrupts = <28>;
-			clocks = <&apb0_gates 5>;
+			clocks = <&ccu CLK_APB0_PIO>;
 			gpio-controller;
 			interrupt-controller;
 			#interrupt-cells = <3>;
@@ -914,7 +506,7 @@
 		pwm: pwm@01c20e00 {
 			compatible = "allwinner,sun5i-a10s-pwm";
 			reg = <0x01c20e00 0xc>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_HOSC>;
 			#pwm-cells = <3>;
 			status = "disabled";
 		};
@@ -923,7 +515,7 @@
 			compatible = "allwinner,sun4i-a10-timer";
 			reg = <0x01c20c00 0x90>;
 			interrupts = <22>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_HOSC>;
 		};
 
 		wdt: watchdog@01c20c90 {
@@ -936,7 +528,7 @@
 			compatible = "allwinner,sun4i-a10-spdif";
 			reg = <0x01c21000 0x400>;
 			interrupts = <13>;
-			clocks = <&apb0_gates 1>, <&spdif_clk>;
+			clocks = <&ccu CLK_APB0_SPDIF>, <&ccu CLK_SPDIF>;
 			clock-names = "apb", "spdif";
 			dmas = <&dma SUN4I_DMA_NORMAL 2>,
 			       <&dma SUN4I_DMA_NORMAL 2>;
@@ -946,7 +538,7 @@
 
 		ir0: ir@01c21800 {
 			compatible = "allwinner,sun4i-a10-ir";
-			clocks = <&apb0_gates 6>, <&ir0_clk>;
+			clocks = <&ccu CLK_APB0_IR>, <&ccu CLK_IR>;
 			clock-names = "apb", "ir";
 			interrupts = <5>;
 			reg = <0x01c21800 0x40>;
@@ -958,7 +550,7 @@
 			compatible = "allwinner,sun4i-a10-i2s";
 			reg = <0x01c22400 0x400>;
 			interrupts = <16>;
-			clocks = <&apb0_gates 3>, <&i2s0_clk>;
+			clocks = <&ccu CLK_APB0_I2S>, <&ccu CLK_I2S>;
 			clock-names = "apb", "mod";
 			dmas = <&dma SUN4I_DMA_NORMAL 3>,
 			       <&dma SUN4I_DMA_NORMAL 3>;
@@ -978,7 +570,7 @@
 			compatible = "allwinner,sun4i-a10-codec";
 			reg = <0x01c22c00 0x40>;
 			interrupts = <30>;
-			clocks = <&apb0_gates 0>, <&codec_clk>;
+			clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
 			clock-names = "apb", "codec";
 			dmas = <&dma SUN4I_DMA_NORMAL 19>,
 			       <&dma SUN4I_DMA_NORMAL 19>;
@@ -999,7 +591,7 @@
 			interrupts = <2>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 17>;
+			clocks = <&ccu CLK_APB1_UART1>;
 			status = "disabled";
 		};
 
@@ -1009,7 +601,7 @@
 			interrupts = <3>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&apb1_gates 18>;
+			clocks = <&ccu CLK_APB1_UART2>;
 			status = "disabled";
 		};
 
@@ -1027,7 +619,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2ac00 0x400>;
 			interrupts = <7>;
-			clocks = <&apb1_gates 0>;
+			clocks = <&ccu CLK_APB1_I2C0>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1037,7 +629,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2b000 0x400>;
 			interrupts = <8>;
-			clocks = <&apb1_gates 1>;
+			clocks = <&ccu CLK_APB1_I2C1>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1047,7 +639,7 @@
 			compatible = "allwinner,sun4i-a10-i2c";
 			reg = <0x01c2b400 0x400>;
 			interrupts = <9>;
-			clocks = <&apb1_gates 2>;
+			clocks = <&ccu CLK_APB1_I2C2>;
 			status = "disabled";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -1057,18 +649,18 @@
 			compatible = "allwinner,sun5i-a13-hstimer";
 			reg = <0x01c60000 0x1000>;
 			interrupts = <82>, <83>;
-			clocks = <&ahb_gates 28>;
+			clocks = <&ccu CLK_AHB_HSTIMER>;
 		};
 
 		fe0: display-frontend@01e00000 {
 			compatible = "allwinner,sun5i-a13-display-frontend";
 			reg = <0x01e00000 0x20000>;
 			interrupts = <47>;
-			clocks = <&ahb_gates 46>, <&de_fe_clk>,
-				 <&dram_gates 25>;
+			clocks = <&ccu CLK_AHB_DE_FE>, <&ccu CLK_DE_FE>,
+				 <&ccu CLK_DRAM_DE_FE>;
 			clock-names = "ahb", "mod",
 				      "ram";
-			resets = <&de_fe_clk>;
+			resets = <&ccu RST_DE_FE>;
 			status = "disabled";
 
 			ports {
@@ -1091,14 +683,14 @@
 		be0: display-backend@01e60000 {
 			compatible = "allwinner,sun5i-a13-display-backend";
 			reg = <0x01e60000 0x10000>;
-			clocks = <&ahb_gates 44>, <&de_be_clk>,
-				 <&dram_gates 26>;
+			clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
+				 <&ccu CLK_DRAM_DE_BE>;
 			clock-names = "ahb", "mod",
 				      "ram";
-			resets = <&de_be_clk>;
+			resets = <&ccu RST_DE_BE>;
 			status = "disabled";
 
-			assigned-clocks = <&de_be_clk>;
+			assigned-clocks = <&ccu CLK_DE_BE>;
 			assigned-clock-rates = <300000000>;
 
 			ports {
-- 
git-series 0.8.11

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

* Re: [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support
  2016-11-08 17:23 ` [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support Maxime Ripard
@ 2016-11-10  6:18   ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-10  6:18 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Nit: Typo in the subject ("fractional"). Maybe mention what clock on what SoC
needs this in the commit message?

Otherwise,

Acked-by: Chen-Yu Tsai <wens@csie.org>

> ---
>  drivers/clk/sunxi-ng/ccu_mult.c | 8 ++++++++
>  drivers/clk/sunxi-ng/ccu_mult.h | 2 ++
>  2 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
> index 678b6cb49f01..826302464650 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.c
> +++ b/drivers/clk/sunxi-ng/ccu_mult.c
> @@ -75,6 +75,9 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
>         unsigned long val;
>         u32 reg;
>
> +       if (ccu_frac_helper_is_enabled(&cm->common, &cm->frac))
> +               return ccu_frac_helper_read_rate(&cm->common, &cm->frac);
> +
>         reg = readl(cm->common.base + cm->common.reg);
>         val = reg >> cm->mult.shift;
>         val &= (1 << cm->mult.width) - 1;
> @@ -102,6 +105,11 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
>         unsigned long flags;
>         u32 reg;
>
> +       if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
> +               return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
> +       else
> +               ccu_frac_helper_disable(&cm->common, &cm->frac);
> +
>         ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
>                                                 &parent_rate);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
> index c1a2134bdc71..bd2e38b5a32a 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.h
> +++ b/drivers/clk/sunxi-ng/ccu_mult.h
> @@ -2,6 +2,7 @@
>  #define _CCU_MULT_H_
>
>  #include "ccu_common.h"
> +#include "ccu_frac.h"
>  #include "ccu_mux.h"
>
>  struct ccu_mult_internal {
> @@ -23,6 +24,7 @@ struct ccu_mult_internal {
>  struct ccu_mult {
>         u32                     enable;
>
> +       struct ccu_frac_internal        frac;
>         struct ccu_mult_internal        mult;
>         struct ccu_mux_internal mux;
>         struct ccu_common       common;
> --
> git-series 0.8.11

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

* Re: [PATCH 10/10] ARM: gr8: Convert to CCU
  2016-11-08 17:23 ` [PATCH 10/10] ARM: gr8: " Maxime Ripard
@ 2016-11-12 23:51   ` kbuild test robot
  0 siblings, 0 replies; 23+ messages in thread
From: kbuild test robot @ 2016-11-12 23:51 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: kbuild-all, Mike Turquette, Stephen Boyd, Chen-Yu Tsai,
	Maxime Ripard, linux-arm-kernel, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 802 bytes --]

Hi Maxime,

[auto build test ERROR on ]

url:    https://github.com/0day-ci/linux/commits/Maxime-Ripard/ARM-sun5i-Convert-sun5i-SoCs-to-sunxi-ng/20161109-014935
base:    
config: arm-pxa168_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> ERROR: Input tree has errors, aborting (use -f to force output)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 11419 bytes --]

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

* Re: [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers
  2016-11-08 17:23 ` [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers Maxime Ripard
@ 2016-11-13  3:48   ` Chen-Yu Tsai
  2016-11-13  3:49     ` Chen-Yu Tsai
  0 siblings, 1 reply; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  3:48 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:

It'd be better if you mentioned what clock needs this.

> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 17 ++++++++++++++---
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 9b840a47a94d..fd3c6a9d987c 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>                                         unsigned long parent_rate)
>  {
>         struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
> -       unsigned long n, m, k;
> +       unsigned long rate, n, m, k;
>         u32 reg;
>
>         reg = readl(nkm->common.base + nkm->common.reg);
> @@ -89,7 +89,11 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>         m = reg >> nkm->m.shift;
>         m &= (1 << nkm->m.width) - 1;
>
> -       return parent_rate * (n + 1) * (k + 1) / (m + 1);
> +       rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> +               rate /= nkm->fixed_post_div;
> +
> +       return rate;
>  }
>
>  static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
> @@ -100,6 +104,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>         struct ccu_nkm *nkm = data;
>         struct _ccu_nkm _nkm;
>
> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> +               rate *= nkm->fixed_post_div;
> +
>         _nkm.min_n = nkm->n.min;
>         _nkm.max_n = 1 << nkm->n.width;
>         _nkm.min_k = nkm->k.min;
> @@ -109,7 +116,11 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>
>         ccu_nkm_find_best(parent_rate, rate, &_nkm);
>
> -       return parent_rate * _nkm.n * _nkm.k / _nkm.m;
> +       rate = parent_rate * _nkm.n * _nkm.k / _nkm.m;
> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> +               rate = rate / nkm->fixed_post_div;
> +
> +       return rate;
>  }
>

You also need to handle this in the set_rate callback. You might need
to read back
the parent index value to determine if the post divider applies, as
this clock supports
a mux. Or don't support mux + post-div, and leave a TODO note.

ChenYu

>  static int ccu_nkm_determine_rate(struct clk_hw *hw,
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index 34580894f4d1..0f1dbca25719 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -32,6 +32,8 @@ struct ccu_nkm {
>         struct ccu_mult_internal        n;
>         struct ccu_mult_internal        k;
>         struct ccu_div_internal         m;
> +
> +       unsigned int            fixed_post_div;
>         struct ccu_mux_internal mux;
>
>         struct ccu_common       common;
> --
> git-series 0.8.11

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

* Re: [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers
  2016-11-13  3:48   ` Chen-Yu Tsai
@ 2016-11-13  3:49     ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  3:49 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Mike Turquette, Stephen Boyd, linux-arm-kernel,
	linux-kernel, linux-clk

On Sun, Nov 13, 2016 at 11:48 AM, Chen-Yu Tsai <wens@csie.org> wrote:
> On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>
> It'd be better if you mentioned what clock needs this.
>
>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> ---
>>  drivers/clk/sunxi-ng/ccu_nkm.c | 17 ++++++++++++++---
>>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>>  2 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
>> index 9b840a47a94d..fd3c6a9d987c 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
>> @@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>>                                         unsigned long parent_rate)
>>  {
>>         struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
>> -       unsigned long n, m, k;
>> +       unsigned long rate, n, m, k;
>>         u32 reg;
>>
>>         reg = readl(nkm->common.base + nkm->common.reg);
>> @@ -89,7 +89,11 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>>         m = reg >> nkm->m.shift;
>>         m &= (1 << nkm->m.width) - 1;
>>
>> -       return parent_rate * (n + 1) * (k + 1) / (m + 1);
>> +       rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
>> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>> +               rate /= nkm->fixed_post_div;
>> +
>> +       return rate;
>>  }
>>
>>  static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>> @@ -100,6 +104,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>>         struct ccu_nkm *nkm = data;
>>         struct _ccu_nkm _nkm;
>>
>> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>> +               rate *= nkm->fixed_post_div;
>> +
>>         _nkm.min_n = nkm->n.min;
>>         _nkm.max_n = 1 << nkm->n.width;
>>         _nkm.min_k = nkm->k.min;
>> @@ -109,7 +116,11 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>>
>>         ccu_nkm_find_best(parent_rate, rate, &_nkm);
>>
>> -       return parent_rate * _nkm.n * _nkm.k / _nkm.m;
>> +       rate = parent_rate * _nkm.n * _nkm.k / _nkm.m;
>> +       if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>> +               rate = rate / nkm->fixed_post_div;
>> +
>> +       return rate;
>>  }
>>
>
> You also need to handle this in the set_rate callback. You might need
> to read back
> the parent index value to determine if the post divider applies, as
> this clock supports
> a mux. Or don't support mux + post-div, and leave a TODO note.

Was thinking pre-dividers... sorry. Please ignore the second parent
index part.

ChenYu

>
> ChenYu
>
>>  static int ccu_nkm_determine_rate(struct clk_hw *hw,
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
>> index 34580894f4d1..0f1dbca25719 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
>> @@ -32,6 +32,8 @@ struct ccu_nkm {
>>         struct ccu_mult_internal        n;
>>         struct ccu_mult_internal        k;
>>         struct ccu_div_internal         m;
>> +
>> +       unsigned int            fixed_post_div;
>>         struct ccu_mux_internal mux;
>>
>>         struct ccu_common       common;
>> --
>> git-series 0.8.11

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

* Re: [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets
  2016-11-08 17:23 ` [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets Maxime Ripard
@ 2016-11-13  4:18   ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  4:18 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The multipliers we've seen so far all had an offset of one. However, on the

Explaining that the offset refers to the difference between the register value
and the actual multiplier/divider applied to the clock rate would be nice.

> earlier Allwinner SoCs, the multipliers could have no offset at all.
>
> Implement an additional field for the multipliers to specify that offset.

You are also doing this for dividers. Please mention that.

And you should mention that you're only doing this for "linear" factors,
not power-of-two ones.

>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/ccu_div.h  | 10 +++++++++-
>  drivers/clk/sunxi-ng/ccu_mp.c   | 10 +++++++---
>  drivers/clk/sunxi-ng/ccu_mult.c |  4 ++--
>  drivers/clk/sunxi-ng/ccu_mult.h | 20 ++++++++++++++------
>  drivers/clk/sunxi-ng/ccu_nk.c   | 14 ++++++++++----
>  drivers/clk/sunxi-ng/ccu_nkm.c  | 18 +++++++++++++-----
>  drivers/clk/sunxi-ng/ccu_nkmp.c | 17 +++++++++++++----
>  drivers/clk/sunxi-ng/ccu_nm.c   | 13 ++++++++++---
>  8 files changed, 78 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
> index 06540f7cf41c..08d074451204 100644
> --- a/drivers/clk/sunxi-ng/ccu_div.h
> +++ b/drivers/clk/sunxi-ng/ccu_div.h
> @@ -41,6 +41,7 @@ struct ccu_div_internal {
>         u8                      width;
>
>         u32                     max;
> +       u32                     offset;
>
>         u32                     flags;
>
> @@ -58,20 +59,27 @@ struct ccu_div_internal {
>  #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table)                   \
>         _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
>
> -#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
> +#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
>         {                                                               \
>                 .shift  = _shift,                                       \
>                 .width  = _width,                                       \
>                 .flags  = _flags,                                       \
>                 .max    = _max,                                         \
> +               .offset = _off,                                         \
>         }
>
> +#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags)         \
> +       _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
> +
>  #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags)                   \
>         _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
>
>  #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max)                       \
>         _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
>
> +#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset)                 \
> +       _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
> +

With this macro, you can have a divider offset of anything but 1, but
no specified maximum. You should handle this in the callbacks somehow.
Same goes for the multiplier. Otherwise with max = (1 << width), you'll
overflow the register field when offset = 0.

Also, if specified, does the maximum apply before or after the offset
is applied? Some clarification is required.

>  #define _SUNXI_CCU_DIV(_shift, _width)                                 \
>         _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
> index ebb1b31568a5..22c2ca7a2a22 100644
> --- a/drivers/clk/sunxi-ng/ccu_mp.c
> +++ b/drivers/clk/sunxi-ng/ccu_mp.c
> @@ -89,11 +89,14 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
>
>         m = reg >> cmp->m.shift;
>         m &= (1 << cmp->m.width) - 1;
> +       m += cmp->m.offset;
> +       if (!m)
> +               m++;
>
>         p = reg >> cmp->p.shift;
>         p &= (1 << cmp->p.width) - 1;
>
> -       return (parent_rate >> p) / (m + 1);
> +       return (parent_rate >> p) / m;
>  }
>
>  static int ccu_mp_determine_rate(struct clk_hw *hw,
> @@ -124,9 +127,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg = readl(cmp->common.base + cmp->common.reg);
>         reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
>         reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
> +       reg |= (m - cmp->m.offset) << cmp->m.shift;
> +       reg |= ilog2(p) << cmp->p.shift;
>
> -       writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
> -              cmp->common.base + cmp->common.reg);
> +       writel(reg, cmp->common.base + cmp->common.reg);
>
>         spin_unlock_irqrestore(cmp->common.lock, flags);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
> index 826302464650..bf5e11c803f9 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.c
> +++ b/drivers/clk/sunxi-ng/ccu_mult.c
> @@ -85,7 +85,7 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
>         ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
>                                                 &parent_rate);
>
> -       return parent_rate * (val + 1);
> +       return parent_rate * (val + cm->mult.offset);
>  }
>
>  static int ccu_mult_determine_rate(struct clk_hw *hw,
> @@ -122,7 +122,7 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg = readl(cm->common.base + cm->common.reg);
>         reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
>
> -       writel(reg | ((_cm.mult - 1) << cm->mult.shift),
> +       writel(reg | ((_cm.mult - cm->mult.offset) << cm->mult.shift),
>                cm->common.base + cm->common.reg);
>
>         spin_unlock_irqrestore(cm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
> index bd2e38b5a32a..84839641dfdf 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.h
> +++ b/drivers/clk/sunxi-ng/ccu_mult.h
> @@ -6,20 +6,28 @@
>  #include "ccu_mux.h"
>
>  struct ccu_mult_internal {
> +       u8      offset;
>         u8      shift;
>         u8      width;
>         u8      min;
>  };
>
> -#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)      \
> -       {                                               \
> -               .shift  = _shift,                       \
> -               .width  = _width,                       \
> -               .min    = _min,                         \
> +#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min)      \
> +       {                                                               \
> +               .min    = _min,                                         \
> +               .offset = _offset,                                      \
> +               .shift  = _shift,                                       \
> +               .width  = _width,                                       \
>         }
>
> +#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)      \
> +       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
> +
> +#define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset)        \
> +       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
> +
>  #define _SUNXI_CCU_MULT(_shift, _width)                \
> -       _SUNXI_CCU_MULT_MIN(_shift, _width, 1)
> +       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
>
>  struct ccu_mult {
>         u32                     enable;
> diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
> index eaf0fdf78d2b..90117d3ead8c 100644
> --- a/drivers/clk/sunxi-ng/ccu_nk.c
> +++ b/drivers/clk/sunxi-ng/ccu_nk.c
> @@ -76,12 +76,17 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw,
>
>         n = reg >> nk->n.shift;
>         n &= (1 << nk->n.width) - 1;
> +       n += nk->n.offset;
> +       if (!n)
> +               n++;
>
>         k = reg >> nk->k.shift;
>         k &= (1 << nk->k.width) - 1;
> +       k += nk->k.offset;
> +       if (!k)
> +               k++;
>
> -       rate = parent_rate * (n + 1) * (k + 1);
> -
> +       rate = parent_rate * n * k;
>         if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
>                 rate /= nk->fixed_post_div;
>
> @@ -135,8 +140,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift);
>         reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift);
>
> -       writel(reg | ((_nk.k - 1) << nk->k.shift) | ((_nk.n - 1) << nk->n.shift),
> -              nk->common.base + nk->common.reg);
> +       reg |= (_nk.k - nk->k.offset) << nk->k.shift;
> +       reg |= (_nk.n - nk->n.offset) << nk->n.shift;
> +       writel(reg, nk->common.base + nk->common.reg);
>
>         spin_unlock_irqrestore(nk->common.lock, flags);
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index fd3c6a9d987c..e0b4c914d7ac 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -82,14 +82,23 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
>
>         n = reg >> nkm->n.shift;
>         n &= (1 << nkm->n.width) - 1;
> +       n += nkm->n.offset;
> +       if (!n)
> +               n++;
>
>         k = reg >> nkm->k.shift;
>         k &= (1 << nkm->k.width) - 1;
> +       k += nkm->k.offset;
> +       if (!k)
> +               k++;
>
>         m = reg >> nkm->m.shift;
>         m &= (1 << nkm->m.width) - 1;
> +       m += nkm->m.offset;
> +       if (!m)
> +               m++;
>
> -       rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
> +       rate = parent_rate * n  * k / m;
>         if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>                 rate /= nkm->fixed_post_div;
>
> @@ -156,10 +165,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
>         reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);
>
> -       reg |= (_nkm.n - 1) << nkm->n.shift;
> -       reg |= (_nkm.k - 1) << nkm->k.shift;
> -       reg |= (_nkm.m - 1) << nkm->m.shift;
> -
> +       reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
> +       reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
> +       reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
>         writel(reg, nkm->common.base + nkm->common.reg);
>
>         spin_unlock_irqrestore(nkm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
> index 684c42da3ebb..da2bba02b845 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
> @@ -88,17 +88,26 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
>
>         n = reg >> nkmp->n.shift;
>         n &= (1 << nkmp->n.width) - 1;
> +       n += nkmp->n.offset;
> +       if (!n)
> +               n++;
>
>         k = reg >> nkmp->k.shift;
>         k &= (1 << nkmp->k.width) - 1;
> +       k += nkmp->k.offset;
> +       if (!k)
> +               k++;
>
>         m = reg >> nkmp->m.shift;
>         m &= (1 << nkmp->m.width) - 1;
> +       m += nkmp->m.offset;
> +       if (!m)
> +               m++;
>
>         p = reg >> nkmp->p.shift;
>         p &= (1 << nkmp->p.width) - 1;
>
> -       return (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
> +       return parent_rate * n * k >> p / m;
>  }
>
>  static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
> @@ -148,9 +157,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
>         reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
>
> -       reg |= (_nkmp.n - 1) << nkmp->n.shift;
> -       reg |= (_nkmp.k - 1) << nkmp->k.shift;
> -       reg |= (_nkmp.m - 1) << nkmp->m.shift;
> +       reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
> +       reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
> +       reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
>         reg |= ilog2(_nkmp.p) << nkmp->p.shift;
>
>         writel(reg, nkmp->common.base + nkmp->common.reg);
> diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
> index c9f3b6c982f0..158d74e0215f 100644
> --- a/drivers/clk/sunxi-ng/ccu_nm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nm.c
> @@ -80,11 +80,17 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
>
>         n = reg >> nm->n.shift;
>         n &= (1 << nm->n.width) - 1;
> +       n += nm->n.offset;
> +       if (!n)
> +               n++;
>
>         m = reg >> nm->m.shift;
>         m &= (1 << nm->m.width) - 1;
> +       m += nm->m.offset;
> +       if (!m)
> +               m++;
>
> -       return parent_rate * (n + 1) / (m + 1);
> +       return parent_rate * n / m;
>  }
>
>  static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
> @@ -129,8 +135,9 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
>         reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
>         reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
>
> -       writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift),
> -              nm->common.base + nm->common.reg);
> +       reg |= (_nm.n - nm->n.offset) << nm->n.shift;
> +       reg |= (_nm.m - nm->m.offset) << nm->m.shift;
> +       writel(reg, nm->common.base + nm->common.reg);
>
>         spin_unlock_irqrestore(nm->common.lock, flags);
>
> --
> git-series 0.8.11

The existing bits in this patch look good.


Regards
ChenYu

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

* Re: [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i
  2016-11-08 17:23 ` [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i Maxime Ripard
@ 2016-11-13  4:29   ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  4:29 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The SoCs part of the sun5i family share the DTs, so we need consistant
> indices in order to still share the DTs.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  include/dt-bindings/clock/sun5i-ccu.h | 126 +++++++++++++++++++++++++++-
>  include/dt-bindings/reset/sun5i-ccu.h |  32 +++++++-
>  2 files changed, 158 insertions(+), 0 deletions(-)
>  create mode 100644 include/dt-bindings/clock/sun5i-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun5i-ccu.h
>
> diff --git a/include/dt-bindings/clock/sun5i-ccu.h b/include/dt-bindings/clock/sun5i-ccu.h
> new file mode 100644
> index 000000000000..32735b2cf29c
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun5i-ccu.h
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright 2016 Maxime Ripard
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _CCU_SUN5I_H_
> +#define _CCU_SUN5I_H_
> +
> +#define CLK_HOSC               1
> +#define CLK_OSC3M              2

We don't need this one. The clock diagram shows the video PLLs' input
as OSC24M. This means there's a fixed /8 pre-divider at the input.

> +#define CLK_PLL_CORE           3
> +#define CLK_PLL_AUDIO_BASE     4
> +#define CLK_PLL_AUDIO          5
> +#define CLK_PLL_AUDIO_2X       6
> +#define CLK_PLL_AUDIO_4X       7
> +#define CLK_PLL_AUDIO_8X       8
> +#define CLK_PLL_VIDEO0         9
> +#define CLK_PLL_VIDEO0_2X      10
> +#define CLK_PLL_VE             11
> +#define CLK_PLL_DDR_BASE       12
> +#define CLK_PLL_DDR            13
> +#define CLK_PLL_DDR_OTHER      14
> +#define CLK_PLL_PERIPH         15
> +#define CLK_PLL_VIDEO1         16
> +#define CLK_PLL_VIDEO1_2X      17
> +#define CLK_OSC24M             18
> +#define CLK_CPU                        19
> +#define CLK_AXI                        20
> +#define CLK_AHB                        21
> +#define CLK_APB0               22
> +#define CLK_APB1               23
> +#define CLK_DRAM_AXI           24
> +#define CLK_AHB_OTG            25
> +#define CLK_AHB_EHCI           26
> +#define CLK_AHB_OHCI           27
> +#define CLK_AHB_SS             28
> +#define CLK_AHB_DMA            29
> +#define CLK_AHB_BIST           30
> +#define CLK_AHB_MMC0           31
> +#define CLK_AHB_MMC1           32
> +#define CLK_AHB_MMC2           33
> +#define CLK_AHB_NAND           34
> +#define CLK_AHB_SDRAM          35
> +#define CLK_AHB_EMAC           36
> +#define CLK_AHB_TS             37
> +#define CLK_AHB_SPI0           38
> +#define CLK_AHB_SPI1           39
> +#define CLK_AHB_SPI2           40
> +#define CLK_AHB_GPS            41
> +#define CLK_AHB_HSTIMER                42
> +#define CLK_AHB_VE             43
> +#define CLK_AHB_TVE            44
> +#define CLK_AHB_LCD            45
> +#define CLK_AHB_CSI            46
> +#define CLK_AHB_HDMI           47
> +#define CLK_AHB_DE_BE          48
> +#define CLK_AHB_DE_FE          49
> +#define CLK_AHB_IEP            50
> +#define CLK_AHB_GPU            51
> +#define CLK_APB0_CODEC         52
> +#define CLK_APB0_SPDIF         53
> +#define CLK_APB0_I2S           54
> +#define CLK_APB0_PIO           55
> +#define CLK_APB0_IR            56
> +#define CLK_APB0_KEYPAD                57
> +#define CLK_APB1_I2C0          58
> +#define CLK_APB1_I2C1          59
> +#define CLK_APB1_I2C2          60
> +#define CLK_APB1_UART0         61
> +#define CLK_APB1_UART1         62
> +#define CLK_APB1_UART2         63
> +#define CLK_APB1_UART3         64
> +#define CLK_NAND               65
> +#define CLK_MMC0               66
> +#define CLK_MMC1               67
> +#define CLK_MMC2               68
> +#define CLK_TS                 69
> +#define CLK_SS                 70
> +#define CLK_CE                 71

You use 'SS' for the AHB gate. Since the manual uses 'SS',
can we stick to that.

> +#define CLK_SPI0               72
> +#define CLK_SPI1               73
> +#define CLK_SPI2               74
> +#define CLK_IR                 75
> +#define CLK_I2S                        76
> +#define CLK_SPDIF              77
> +#define CLK_KEYPAD             78
> +#define CLK_USB_OHCI           79
> +#define CLK_USB_PHY0           80
> +#define CLK_USB_PHY1           81
> +#define CLK_GPS                        82
> +#define CLK_DRAM_VE            83
> +#define CLK_DRAM_CSI           84
> +#define CLK_DRAM_TS            85
> +#define CLK_DRAM_TVE           86
> +#define CLK_DRAM_DE_FE         87
> +#define CLK_DRAM_DE_BE         88
> +#define CLK_DRAM_ACE           89
> +#define CLK_DRAM_IEP           90
> +#define CLK_DE_BE              91
> +#define CLK_DE_FE              92
> +#define CLK_TCON_CH0           93
> +#define CLK_TCON_CH1_SCLK      94
> +#define CLK_TCON_CH1           95
> +#define CLK_CSI                        96
> +#define CLK_VE                 97
> +#define CLK_CODEC              98
> +#define CLK_AVS                        99
> +#define CLK_HDMI               100
> +#define CLK_GPU                        101
> +#define CLK_MBUS               102
> +#define CLK_IEP                        103
> +
> +#define CLK_NUMBER             (CLK_IEP + 1)
> +
> +#endif /* _CCU_SUN5I_H_ */
> diff --git a/include/dt-bindings/reset/sun5i-ccu.h b/include/dt-bindings/reset/sun5i-ccu.h
> new file mode 100644
> index 000000000000..c2b9726b5026
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun5i-ccu.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2016 Maxime Ripard
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _RST_SUN5I_H_
> +#define _RST_SUN5I_H_
> +
> +#define RST_USB_PHY0   0
> +#define RST_USB_PHY1   1
> +#define RST_GPS                2
> +#define RST_DE_BE      3
> +#define RST_DE_FE      4
> +#define RST_TVE                5
> +#define RST_LCD                6
> +#define RST_CSI                7
> +#define RST_VE         8
> +#define RST_GPU                9
> +#define RST_IEP                10
> +
> +#endif /* _RST_SUN5I_H_ */
> --
> git-series 0.8.11

The rest looks good.

ChenYu

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

* Re: [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum
  2016-11-08 17:23 ` [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum Maxime Ripard
@ 2016-11-13  4:30   ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  4:30 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/ccu_mult.h | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
> index 84839641dfdf..524acddfcb2e 100644
> --- a/drivers/clk/sunxi-ng/ccu_mult.h
> +++ b/drivers/clk/sunxi-ng/ccu_mult.h
> @@ -10,24 +10,26 @@ struct ccu_mult_internal {
>         u8      shift;
>         u8      width;
>         u8      min;
> +       u8      max;
>  };
>
> -#define _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, _min)      \
> +#define _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, _min, _max) \
>         {                                                               \
>                 .min    = _min,                                         \
> +               .max    = _max,                                         \
>                 .offset = _offset,                                      \
>                 .shift  = _shift,                                       \
>                 .width  = _width,                                       \
>         }
>
>  #define _SUNXI_CCU_MULT_MIN(_shift, _width, _min)      \
> -       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, _min)
> +       _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, _min, 0)
>
>  #define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset)        \
> -       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, _offset, 1)
> +       _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, 1, 0)
>
>  #define _SUNXI_CCU_MULT(_shift, _width)                \
> -       _SUNXI_CCU_MULT_OFFSET_MIN(_shift, _width, 1, 1)
> +       _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, 1, 0)
>
>  struct ccu_mult {
>         u32                     enable;
> --
> git-series 0.8.11

You're missing the code that actually uses the maximum value.

ChenYu

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

* Re: [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver
  2016-11-08 17:23 ` [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver Maxime Ripard
@ 2016-11-13  9:34   ` Chen-Yu Tsai
  2016-11-21 21:45     ` Maxime Ripard
  0 siblings, 1 reply; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  9:34 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig          |  10 +-
>  drivers/clk/sunxi-ng/Makefile         |   1 +-
>  drivers/clk/sunxi-ng/ccu-sun5i-a10s.c | 755 +++++++++++++++++++++++++++-
>  drivers/clk/sunxi-ng/ccu-sun5i.h      | 129 +++++-
>  4 files changed, 895 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i.h
>
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index 8454c6e3dd65..e2becd36a1f9 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -64,6 +64,16 @@ config SUN50I_A64_CCU
>         select SUNXI_CCU_PHASE
>         default ARM64 && ARCH_SUNXI
>
> +config SUN5I_A10S_CCU
> +       bool "Support for the Allwinner A10s CCM"
> +       select SUNXI_CCU_DIV
> +       select SUNXI_CCU_NK
> +       select SUNXI_CCU_NKM
> +       select SUNXI_CCU_NM
> +       select SUNXI_CCU_MP
> +       select SUNXI_CCU_PHASE
> +       default MACH_SUN5I
> +
>  config SUN6I_A31_CCU
>         bool "Support for the Allwinner A31/A31s CCU"
>         select SUNXI_CCU_DIV
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index 24fbc6e5deb8..79e9a166dc83 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_SUNXI_CCU_MP)    += ccu_mp.o
>
>  # SoC support
>  obj-$(CONFIG_SUN50I_A64_CCU)   += ccu-sun50i-a64.o
> +obj-$(CONFIG_SUN5I_A10S_CCU)   += ccu-sun5i-a10s.o
>  obj-$(CONFIG_SUN6I_A31_CCU)    += ccu-sun6i-a31.o
>  obj-$(CONFIG_SUN8I_A23_CCU)    += ccu-sun8i-a23.o
>  obj-$(CONFIG_SUN8I_A33_CCU)    += ccu-sun8i-a33.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
> new file mode 100644
> index 000000000000..94d9a5cbf60b
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
> @@ -0,0 +1,755 @@
> +/*
> + * Copyright (c) 2016 Maxime Ripard. All rights reserved.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +#include "ccu_phase.h"
> +
> +#include "ccu-sun5i.h"
> +
> +static struct ccu_nkmp pll_core_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .m              = _SUNXI_CCU_DIV(0, 2),
> +       .p              = _SUNXI_CCU_DIV(16, 2),
> +       .common         = {
> +               .reg            = 0x000,
> +               .hw.init        = CLK_HW_INIT("pll-core",
> +                                             "hosc",
> +                                             &ccu_nkmp_ops,
> +                                             0),
> +       },
> +};
> +
> +/*
> + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
> + * the base (2x, 4x and 8x), and one variable divider (the one true
> + * pll audio).
> + *
> + * We don't have any need for the variable divider for now, so we just
> + * hardcode it to match with the clock names
> + */
> +#define SUN5I_PLL_AUDIO_REG    0x008
> +
> +static struct ccu_nm pll_audio_base_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
> +       .m              = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),

Nit: a note explaining that the datasheet is wrong would be nice.

> +       .common         = {
> +               .reg            = 0x008,
> +               .hw.init        = CLK_HW_INIT("pll-audio-base",
> +                                             "hosc",
> +                                             &ccu_nm_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_mult pll_video0_clk = {
> +       .enable         = BIT(31),
> +       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
> +       .frac           = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
> +                                         270000000, 297000000),
> +       .common         = {
> +               .reg            = 0x010,
> +               .features       = CCU_FEATURE_FRACTIONAL,
> +               .hw.init        = CLK_HW_INIT("pll-video0",
> +                                             "osc3M",
> +                                             &ccu_mult_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nkmp pll_ve_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .m              = _SUNXI_CCU_DIV(0, 2),
> +       .p              = _SUNXI_CCU_DIV(16, 2),

Any chance we'll support the bypass switch on this one?

> +       .common         = {
> +               .reg            = 0x018,
> +               .hw.init        = CLK_HW_INIT("pll-ve",
> +                                             "hosc",
> +                                             &ccu_nkmp_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nk pll_ddr_base_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .common         = {
> +               .reg            = 0x020,
> +               .hw.init        = CLK_HW_INIT("pll-ddr-base",
> +                                             "hosc",
> +                                             &ccu_nk_ops,
> +                                             0),
> +       },
> +};
> +
> +static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);

Maybe we should set CLK_IS_CRITICAL on this one as well... in case the
bootloader uses pll-periph for mbus, and none of the dram gates are enabled.

> +
> +static struct ccu_div pll_ddr_other_clk = {
> +       .div            = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
> +
> +       .common         = {
> +               .reg            = 0x020,
> +               .hw.init        = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
> +                                             &ccu_div_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nk pll_periph_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .fixed_post_div = 2,
> +       .common         = {
> +               .reg            = 0x028,
> +               .features       = CCU_FEATURE_FIXED_POSTDIV,
> +               .hw.init        = CLK_HW_INIT("pll-periph",
> +                                             "hosc",
> +                                             &ccu_nk_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_mult pll_video1_clk = {
> +       .enable         = BIT(31),
> +       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
> +       .frac           = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
> +                                 270000000, 297000000),
> +       .common         = {
> +               .reg            = 0x030,
> +               .features       = CCU_FEATURE_FRACTIONAL,
> +               .hw.init        = CLK_HW_INIT("pll-video1",
> +                                             "osc3M",
> +                                             &ccu_mult_ops,
> +                                             0),
> +       },
> +};
> +
> +static SUNXI_CCU_GATE(hosc_clk,        "hosc", "osc24M", 0x050, BIT(0), 0);

Why the extra "hosc" clock here? You should probably just internalize "osc24M".

> +
> +#define SUN5I_AHB_REG  0x054
> +static const char * const cpu_parents[] = { "osc32k", "hosc",
> +                                           "pll-core" , "pll-periph" };
> +static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
> +       { .index = 3, .div = 3, },
> +};
> +static struct ccu_mux cpu_clk = {
> +       .mux            = {
> +               .shift          = 16,
> +               .width          = 2,
> +               .fixed_predivs  = cpu_predivs,
> +               .n_predivs      = ARRAY_SIZE(cpu_predivs),
> +       },
> +       .common         = {
> +               .reg            = 0x054,
> +               .features       = CCU_FEATURE_FIXED_PREDIV,
> +               .hw.init        = CLK_HW_INIT_PARENTS("cpu",
> +                                                     cpu_parents,
> +                                                     &ccu_mux_ops,
> +                                                     CLK_IS_CRITICAL),
> +       }
> +};
> +
> +static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
> +
> +static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
> +static struct ccu_div ahb_clk = {
> +       .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
> +       .mux            = _SUNXI_CCU_MUX(6, 2),

There's a fixed /2 pre-divider on pll-periph.

> +
> +       .common         = {
> +               .reg            = 0x054,
> +               .hw.init        = CLK_HW_INIT_PARENTS("ahb",
> +                                                     ahb_parents,
> +                                                     &ccu_div_ops,
> +                                                     0),
> +       },
> +};
> +
> +static struct clk_div_table apb0_div_table[] = {
> +       { .val = 0, .div = 2 },
> +       { .val = 1, .div = 2 },
> +       { .val = 2, .div = 4 },
> +       { .val = 3, .div = 8 },
> +       { /* Sentinel */ },
> +};
> +static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
> +                          0x054, 8, 2, apb0_div_table, 0);
> +
> +static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
> +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
> +                            0, 5,      /* M */
> +                            16, 2,     /* P */
> +                            24, 2,     /* mux */
> +                            0);
> +
> +static SUNXI_CCU_GATE(axi_dram_clk,    "axi-dram",     "axi",
> +                     0x05c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(ahb_otg_clk,     "ahb-otg",      "ahb",
> +                     0x060, BIT(0), 0);
> +static SUNXI_CCU_GATE(ahb_ehci_clk,    "ahb-ehci",     "ahb",
> +                     0x060, BIT(1), 0);
> +static SUNXI_CCU_GATE(ahb_ohci_clk,    "ahb-ohci",     "ahb",
> +                     0x060, BIT(2), 0);
> +static SUNXI_CCU_GATE(ahb_ss_clk,      "ahb-ss",       "ahb",
> +                     0x060, BIT(5), 0);
> +static SUNXI_CCU_GATE(ahb_dma_clk,     "ahb-dma",      "ahb",
> +                     0x060, BIT(6), 0);
> +static SUNXI_CCU_GATE(ahb_bist_clk,    "ahb-bist",     "ahb",
> +                     0x060, BIT(6), 0);
> +static SUNXI_CCU_GATE(ahb_mmc0_clk,    "ahb-mmc0",     "ahb",
> +                     0x060, BIT(8), 0);
> +static SUNXI_CCU_GATE(ahb_mmc1_clk,    "ahb-mmc1",     "ahb",
> +                     0x060, BIT(9), 0);
> +static SUNXI_CCU_GATE(ahb_mmc2_clk,    "ahb-mmc2",     "ahb",
> +                     0x060, BIT(10), 0);
> +static SUNXI_CCU_GATE(ahb_nand_clk,    "ahb-nand",     "ahb",
> +                     0x060, BIT(13), 0);
> +static SUNXI_CCU_GATE(ahb_sdram_clk,   "ahb-sdram",    "ahb",
> +                     0x060, BIT(14), CLK_IS_CRITICAL);
> +static SUNXI_CCU_GATE(ahb_emac_clk,    "ahb-emac",     "ahb",
> +                     0x060, BIT(17), 0);
> +static SUNXI_CCU_GATE(ahb_ts_clk,      "ahb-ts",       "ahb",
> +                     0x060, BIT(18), 0);
> +static SUNXI_CCU_GATE(ahb_spi0_clk,    "ahb-spi0",     "ahb",
> +                     0x060, BIT(20), 0);
> +static SUNXI_CCU_GATE(ahb_spi1_clk,    "ahb-spi1",     "ahb",
> +                     0x060, BIT(21), 0);
> +static SUNXI_CCU_GATE(ahb_spi2_clk,    "ahb-spi2",     "ahb",
> +                     0x060, BIT(22), 0);
> +static SUNXI_CCU_GATE(ahb_gps_clk,     "ahb-gps",      "ahb",
> +                     0x060, BIT(26), 0);
> +static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer",  "ahb",
> +                     0x060, BIT(28), 0);
> +
> +static SUNXI_CCU_GATE(ahb_ve_clk,      "ahb-ve",       "ahb",
> +                     0x064, BIT(0), 0);
> +static SUNXI_CCU_GATE(ahb_tve_clk,     "ahb-tve",      "ahb",
> +                     0x064, BIT(2), 0);
> +static SUNXI_CCU_GATE(ahb_lcd_clk,     "ahb-lcd",      "ahb",
> +                     0x064, BIT(4), 0);
> +static SUNXI_CCU_GATE(ahb_csi_clk,     "ahb-csi",      "ahb",
> +                     0x064, BIT(8), 0);
> +static SUNXI_CCU_GATE(ahb_hdmi_clk,    "ahb-hdmi",     "ahb",
> +                     0x064, BIT(11), 0);
> +static SUNXI_CCU_GATE(ahb_de_be_clk,   "ahb-de-be",    "ahb",
> +                     0x064, BIT(12), 0);
> +static SUNXI_CCU_GATE(ahb_de_fe_clk,   "ahb-de-fe",    "ahb",
> +                     0x064, BIT(14), 0);
> +static SUNXI_CCU_GATE(ahb_iep_clk,     "ahb-iep",      "ahb",
> +                     0x064, BIT(19), 0);
> +static SUNXI_CCU_GATE(ahb_gpu_clk,     "ahb-gpu",      "ahb",
> +                     0x064, BIT(20), 0);
> +
> +static SUNXI_CCU_GATE(apb0_codec_clk,  "apb0-codec",   "apb0",
> +                     0x068, BIT(0), 0);
> +static SUNXI_CCU_GATE(apb0_i2s_clk,    "apb0-i2s",     "apb0",
> +                     0x068, BIT(3), 0);
> +static SUNXI_CCU_GATE(apb0_pio_clk,    "apb0-pio",     "apb0",
> +                     0x068, BIT(5), 0);
> +static SUNXI_CCU_GATE(apb0_ir_clk,     "apb0-ir",      "apb0",
> +                     0x068, BIT(6), 0);
> +static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad",  "apb0",
> +                     0x068, BIT(10), 0);
> +
> +static SUNXI_CCU_GATE(apb1_i2c0_clk,   "apb1-i2c0",    "apb1",
> +                     0x06c, BIT(0), 0);
> +static SUNXI_CCU_GATE(apb1_i2c1_clk,   "apb1-i2c1",    "apb1",
> +                     0x06c, BIT(1), 0);
> +static SUNXI_CCU_GATE(apb1_i2c2_clk,   "apb1-i2c2",    "apb1",
> +                     0x06c, BIT(2), 0);
> +static SUNXI_CCU_GATE(apb1_uart0_clk,  "apb1-uart0",   "apb1",
> +                     0x06c, BIT(16), 0);
> +static SUNXI_CCU_GATE(apb1_uart1_clk,  "apb1-uart1",   "apb1",
> +                     0x06c, BIT(17), 0);
> +static SUNXI_CCU_GATE(apb1_uart2_clk,  "apb1-uart2",   "apb1",
> +                     0x06c, BIT(18), 0);
> +static SUNXI_CCU_GATE(apb1_uart3_clk,  "apb1-uart3",   "apb1",
> +                     0x06c, BIT(19), 0);
> +
> +static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
> +                                                    "pll-ddr-other" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
> +                                           "pll-audio-2x", "pll-audio" };
> +static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
> +                              0x0b8, 16, 2, BIT(31), 0);

CLK_SET_RATE_PARENT please.

> +
> +static const char * const keypad_parents[] = { "hosc", "losc"};
> +static const u8 keypad_table[] = { 0, 2 };
> +static struct ccu_mp keypad_clk = {
> +       .enable         = BIT(31),
> +       .m              = _SUNXI_CCU_DIV(8, 5),
> +       .p              = _SUNXI_CCU_DIV(20, 2),
> +       .mux            = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
> +
> +       .common         = {
> +               .reg            = 0x0c4,
> +               .hw.init        = CLK_HW_INIT_PARENTS("keypad",
> +                                                     keypad_parents,
> +                                                     &ccu_mp_ops,
> +                                                     0),
> +       },
> +};
> +
> +static SUNXI_CCU_GATE(usb_ohci_clk,    "usb-ohci",     "pll-periph",
> +                     0x0cc, BIT(6), 0);
> +static SUNXI_CCU_GATE(usb_phy0_clk,    "usb-phy0",     "pll-periph",
> +                     0x0cc, BIT(8), 0);
> +static SUNXI_CCU_GATE(usb_phy1_clk,    "usb-phy1",     "pll-periph",
> +                     0x0cc, BIT(9), 0);
> +
> +static const char * const gps_parents[] = { "hosc", "pll-periph",
> +                                           "pll-video1", "pll-ve" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
> +                                0x0d0, 0, 3, 24, 2, BIT(31), 0);
> +
> +static SUNXI_CCU_GATE(dram_ve_clk,     "dram-ve",      "pll-ddr",
> +                     0x100, BIT(0), 0);
> +static SUNXI_CCU_GATE(dram_csi_clk,    "dram-csi",     "pll-ddr",
> +                     0x100, BIT(1), 0);
> +static SUNXI_CCU_GATE(dram_ts_clk,     "dram-ts",      "pll-ddr",
> +                     0x100, BIT(3), 0);
> +static SUNXI_CCU_GATE(dram_tve_clk,    "dram-tve",     "pll-ddr",
> +                     0x100, BIT(5), 0);
> +static SUNXI_CCU_GATE(dram_de_fe_clk,  "dram-de-fe",   "pll-ddr",
> +                     0x100, BIT(25), 0);
> +static SUNXI_CCU_GATE(dram_de_be_clk,  "dram-de-be",   "pll-ddr",
> +                     0x100, BIT(26), 0);
> +static SUNXI_CCU_GATE(dram_ace_clk,    "dram-ace",     "pll-ddr",
> +                     0x100, BIT(29), 0);
> +static SUNXI_CCU_GATE(dram_iep_clk,    "dram-iep",     "pll-ddr",
> +                     0x100, BIT(31), 0);
> +
> +static const char * const de_parents[] = { "pll-video0", "pll-video1",
> +                                          "pll-ddr-other" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
> +                                0x104, 0, 4, 24, 2, BIT(31), 0);
> +
> +static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
> +                                0x10c, 0, 4, 24, 2, BIT(31), 0);
> +
> +static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
> +                                            "pll-video0-2x", "pll-video1-2x" };
> +static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
> +                              0x118, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
> +                                tcon_parents,
> +                                0x12c, 0, 4, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
> +                            0x12c, 11, 1, BIT(15), 0);

CLK_SET_RATE_PARENT?

> +
> +static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
> +                                           "pll-video0-2x", "pll-video1-2x" };
> +static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
> +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
> +                                      csi_parents, csi_table,
> +                                      0x134, 0, 5, 24, 2, BIT(31), 0);

Do you know if CSI needs to change the module clock?

> +
> +static SUNXI_CCU_GATE(ve_clk,          "ve",           "pll-ve",
> +                     0x13c, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_GATE(codec_clk,       "codec",        "pll-audio",
> +                     0x140, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_GATE(avs_clk,         "avs",          "hosc",
> +                     0x144, BIT(31), 0);
> +
> +static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
> +static const u8 hdmi_table[] = { 0, 2 };
> +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
> +                                      hdmi_parents, hdmi_table,
> +                                      0x150, 0, 4, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
> +                                           "pll-ddr-other", "pll-video1",
> +                                           "pll-video1-2x" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
> +                                0x154, 0, 4, 24, 3, BIT(31), 0);
> +
> +static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
> +                                 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
> +
> +static SUNXI_CCU_GATE(iep_clk,         "iep",          "de-be",
> +                     0x160, BIT(31), 0);
> +
> +static struct ccu_common *sun5i_a10s_ccu_clks[] = {
> +       &hosc_clk.common,
> +       &pll_core_clk.common,
> +       &pll_audio_base_clk.common,
> +       &pll_video0_clk.common,
> +       &pll_ve_clk.common,
> +       &pll_ddr_base_clk.common,
> +       &pll_ddr_clk.common,
> +       &pll_ddr_other_clk.common,
> +       &pll_periph_clk.common,
> +       &pll_video1_clk.common,
> +       &cpu_clk.common,
> +       &axi_clk.common,
> +       &ahb_clk.common,
> +       &apb0_clk.common,
> +       &apb1_clk.common,
> +       &axi_dram_clk.common,
> +       &ahb_otg_clk.common,
> +       &ahb_ehci_clk.common,
> +       &ahb_ohci_clk.common,
> +       &ahb_ss_clk.common,
> +       &ahb_dma_clk.common,
> +       &ahb_bist_clk.common,
> +       &ahb_mmc0_clk.common,
> +       &ahb_mmc1_clk.common,
> +       &ahb_mmc2_clk.common,
> +       &ahb_nand_clk.common,
> +       &ahb_sdram_clk.common,
> +       &ahb_emac_clk.common,
> +       &ahb_ts_clk.common,
> +       &ahb_spi0_clk.common,
> +       &ahb_spi1_clk.common,
> +       &ahb_spi2_clk.common,
> +       &ahb_gps_clk.common,
> +       &ahb_hstimer_clk.common,
> +       &ahb_ve_clk.common,
> +       &ahb_tve_clk.common,
> +       &ahb_lcd_clk.common,
> +       &ahb_csi_clk.common,
> +       &ahb_hdmi_clk.common,
> +       &ahb_de_be_clk.common,
> +       &ahb_de_fe_clk.common,
> +       &ahb_iep_clk.common,
> +       &ahb_gpu_clk.common,
> +       &apb0_codec_clk.common,
> +       &apb0_i2s_clk.common,
> +       &apb0_pio_clk.common,
> +       &apb0_ir_clk.common,
> +       &apb0_keypad_clk.common,
> +       &apb1_i2c0_clk.common,
> +       &apb1_i2c1_clk.common,
> +       &apb1_i2c2_clk.common,
> +       &apb1_uart0_clk.common,
> +       &apb1_uart1_clk.common,
> +       &apb1_uart2_clk.common,
> +       &apb1_uart3_clk.common,
> +       &nand_clk.common,
> +       &mmc0_clk.common,
> +       &mmc1_clk.common,
> +       &mmc2_clk.common,
> +       &ts_clk.common,
> +       &ss_clk.common,
> +       &spi0_clk.common,
> +       &spi1_clk.common,
> +       &spi2_clk.common,
> +       &ir_clk.common,
> +       &i2s_clk.common,
> +       &keypad_clk.common,
> +       &usb_ohci_clk.common,
> +       &usb_phy0_clk.common,
> +       &usb_phy1_clk.common,
> +       &gps_clk.common,
> +       &dram_ve_clk.common,
> +       &dram_csi_clk.common,
> +       &dram_ts_clk.common,
> +       &dram_tve_clk.common,
> +       &dram_de_fe_clk.common,
> +       &dram_de_be_clk.common,
> +       &dram_ace_clk.common,
> +       &dram_iep_clk.common,
> +       &de_be_clk.common,
> +       &de_fe_clk.common,
> +       &tcon_ch0_clk.common,
> +       &tcon_ch1_sclk2_clk.common,
> +       &tcon_ch1_sclk1_clk.common,
> +       &csi_clk.common,
> +       &ve_clk.common,
> +       &codec_clk.common,
> +       &avs_clk.common,
> +       &hdmi_clk.common,
> +       &gpu_clk.common,
> +       &mbus_clk.common,
> +       &iep_clk.common,
> +};
> +
> +static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
> +/* We hardcode the divider to 4 for now */
> +static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
> +                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
> +                       "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
> +                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
> +                       "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
> +                       "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
> +                       "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
> +
> +static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
> +       .hws    = {
> +               [CLK_HOSC]              = &hosc_clk.common.hw,
> +               [CLK_OSC3M]             = &osc3M_clk.hw,
> +               [CLK_PLL_CORE]          = &pll_core_clk.common.hw,
> +               [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
> +               [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
> +               [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
> +               [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
> +               [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
> +               [CLK_PLL_VIDEO0]        = &pll_video0_clk.common.hw,
> +               [CLK_PLL_VIDEO0_2X]     = &pll_video0_2x_clk.hw,
> +               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
> +               [CLK_PLL_DDR_BASE]      = &pll_ddr_base_clk.common.hw,
> +               [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
> +               [CLK_PLL_DDR_OTHER]     = &pll_ddr_other_clk.common.hw,
> +               [CLK_PLL_PERIPH]        = &pll_periph_clk.common.hw,
> +               [CLK_PLL_VIDEO1]        = &pll_video1_clk.common.hw,
> +               [CLK_PLL_VIDEO1_2X]     = &pll_video1_2x_clk.hw,
> +               [CLK_CPU]               = &cpu_clk.common.hw,
> +               [CLK_AXI]               = &axi_clk.common.hw,
> +               [CLK_AHB]               = &ahb_clk.common.hw,
> +               [CLK_APB0]              = &apb0_clk.common.hw,
> +               [CLK_APB1]              = &apb1_clk.common.hw,
> +               [CLK_DRAM_AXI]          = &axi_dram_clk.common.hw,
> +               [CLK_AHB_OTG]           = &ahb_otg_clk.common.hw,
> +               [CLK_AHB_EHCI]          = &ahb_ehci_clk.common.hw,
> +               [CLK_AHB_OHCI]          = &ahb_ohci_clk.common.hw,
> +               [CLK_AHB_SS]            = &ahb_ss_clk.common.hw,
> +               [CLK_AHB_DMA]           = &ahb_dma_clk.common.hw,
> +               [CLK_AHB_BIST]          = &ahb_bist_clk.common.hw,
> +               [CLK_AHB_MMC0]          = &ahb_mmc0_clk.common.hw,
> +               [CLK_AHB_MMC1]          = &ahb_mmc1_clk.common.hw,
> +               [CLK_AHB_MMC2]          = &ahb_mmc2_clk.common.hw,
> +               [CLK_AHB_NAND]          = &ahb_nand_clk.common.hw,
> +               [CLK_AHB_SDRAM]         = &ahb_sdram_clk.common.hw,
> +               [CLK_AHB_EMAC]          = &ahb_emac_clk.common.hw,
> +               [CLK_AHB_TS]            = &ahb_ts_clk.common.hw,
> +               [CLK_AHB_SPI0]          = &ahb_spi0_clk.common.hw,
> +               [CLK_AHB_SPI1]          = &ahb_spi1_clk.common.hw,
> +               [CLK_AHB_SPI2]          = &ahb_spi2_clk.common.hw,
> +               [CLK_AHB_GPS]           = &ahb_gps_clk.common.hw,
> +               [CLK_AHB_HSTIMER]       = &ahb_hstimer_clk.common.hw,
> +               [CLK_AHB_VE]            = &ahb_ve_clk.common.hw,
> +               [CLK_AHB_TVE]           = &ahb_tve_clk.common.hw,
> +               [CLK_AHB_LCD]           = &ahb_lcd_clk.common.hw,
> +               [CLK_AHB_CSI]           = &ahb_csi_clk.common.hw,
> +               [CLK_AHB_HDMI]          = &ahb_hdmi_clk.common.hw,
> +               [CLK_AHB_DE_BE]         = &ahb_de_be_clk.common.hw,
> +               [CLK_AHB_DE_FE]         = &ahb_de_fe_clk.common.hw,
> +               [CLK_AHB_IEP]           = &ahb_iep_clk.common.hw,
> +               [CLK_AHB_GPU]           = &ahb_gpu_clk.common.hw,
> +               [CLK_APB0_CODEC]        = &apb0_codec_clk.common.hw,
> +               [CLK_APB0_I2S]          = &apb0_i2s_clk.common.hw,
> +               [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
> +               [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
> +               [CLK_APB0_KEYPAD]       = &apb0_keypad_clk.common.hw,
> +               [CLK_APB1_I2C0]         = &apb1_i2c0_clk.common.hw,
> +               [CLK_APB1_I2C1]         = &apb1_i2c1_clk.common.hw,
> +               [CLK_APB1_I2C2]         = &apb1_i2c2_clk.common.hw,
> +               [CLK_APB1_UART0]        = &apb1_uart0_clk.common.hw,
> +               [CLK_APB1_UART1]        = &apb1_uart1_clk.common.hw,
> +               [CLK_APB1_UART2]        = &apb1_uart2_clk.common.hw,
> +               [CLK_APB1_UART3]        = &apb1_uart3_clk.common.hw,
> +               [CLK_NAND]              = &nand_clk.common.hw,
> +               [CLK_MMC0]              = &mmc0_clk.common.hw,
> +               [CLK_MMC1]              = &mmc1_clk.common.hw,
> +               [CLK_MMC2]              = &mmc2_clk.common.hw,
> +               [CLK_TS]                = &ts_clk.common.hw,
> +               [CLK_SS]                = &ss_clk.common.hw,
> +               [CLK_SPI0]              = &spi0_clk.common.hw,
> +               [CLK_SPI1]              = &spi1_clk.common.hw,
> +               [CLK_SPI2]              = &spi2_clk.common.hw,
> +               [CLK_IR]                = &ir_clk.common.hw,
> +               [CLK_I2S]               = &i2s_clk.common.hw,
> +               [CLK_KEYPAD]            = &keypad_clk.common.hw,
> +               [CLK_USB_OHCI]          = &usb_ohci_clk.common.hw,
> +               [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
> +               [CLK_USB_PHY1]          = &usb_phy1_clk.common.hw,
> +               [CLK_GPS]               = &gps_clk.common.hw,
> +               [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
> +               [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
> +               [CLK_DRAM_TS]           = &dram_ts_clk.common.hw,
> +               [CLK_DRAM_TVE]          = &dram_tve_clk.common.hw,
> +               [CLK_DRAM_DE_FE]        = &dram_de_fe_clk.common.hw,
> +               [CLK_DRAM_DE_BE]        = &dram_de_be_clk.common.hw,
> +               [CLK_DRAM_ACE]          = &dram_ace_clk.common.hw,
> +               [CLK_DRAM_IEP]          = &dram_iep_clk.common.hw,
> +               [CLK_DE_BE]             = &de_be_clk.common.hw,
> +               [CLK_DE_FE]             = &de_fe_clk.common.hw,
> +               [CLK_TCON_CH0]          = &tcon_ch0_clk.common.hw,
> +               [CLK_TCON_CH1_SCLK]     = &tcon_ch1_sclk2_clk.common.hw,
> +               [CLK_TCON_CH1]          = &tcon_ch1_sclk1_clk.common.hw,
> +               [CLK_CSI]               = &csi_clk.common.hw,
> +               [CLK_VE]                = &ve_clk.common.hw,
> +               [CLK_CODEC]             = &codec_clk.common.hw,
> +               [CLK_AVS]               = &avs_clk.common.hw,
> +               [CLK_HDMI]              = &hdmi_clk.common.hw,
> +               [CLK_GPU]               = &gpu_clk.common.hw,
> +               [CLK_MBUS]              = &mbus_clk.common.hw,
> +               [CLK_IEP]               = &iep_clk.common.hw,
> +       },
> +       .num    = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
> +       [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
> +       [RST_USB_PHY1]          =  { 0x0cc, BIT(1) },
> +
> +       [RST_GPS]               =  { 0x0d0, BIT(30) },
> +
> +       [RST_DE_BE]             =  { 0x104, BIT(30) },
> +
> +       [RST_DE_FE]             =  { 0x10c, BIT(30) },
> +
> +       [RST_TVE]               =  { 0x118, BIT(29) },
> +       [RST_LCD]               =  { 0x118, BIT(30) },
> +
> +       [RST_CSI]               =  { 0x134, BIT(30) },
> +
> +       [RST_VE]                =  { 0x13c, BIT(0) },
> +
> +       [RST_GPU]               =  { 0x154, BIT(30) },
> +
> +       [RST_IEP]               =  { 0x160, BIT(30) },
> +};
> +
> +static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
> +       .ccu_clks       = sun5i_a10s_ccu_clks,
> +       .num_ccu_clks   = ARRAY_SIZE(sun5i_a10s_ccu_clks),
> +
> +       .hw_clks        = &sun5i_a10s_hw_clks,
> +
> +       .resets         = sun5i_a10s_ccu_resets,
> +       .num_resets     = ARRAY_SIZE(sun5i_a10s_ccu_resets),
> +};
> +
> +static void __init sun5i_a10s_ccu_setup(struct device_node *node)
> +{
> +       void __iomem *reg;
> +       u32 val;
> +
> +       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +       if (IS_ERR(reg)) {
> +               pr_err("%s: Could not map the clock registers\n",
> +                      of_node_full_name(node));
> +               return;
> +       }
> +
> +       /* Force the PLL-Audio-1x divider to 4 */
> +       val = readl(reg + SUN5I_PLL_AUDIO_REG);
> +       val &= ~GENMASK(19, 16);
> +       writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
> +
> +       /*
> +        * Use the peripheral PLL as the AHB parent, instead of CPU /
> +        * AXI which have rate changes due to cpufreq.
> +        *
> +        * This is especially a big deal for the HS timer whose parent
> +        * clock is AHB.
> +        */
> +       val = readl(reg + SUN5I_AHB_REG);
> +       val &= ~GENMASK(7, 6);
> +       writel(val | (2 << 6), reg + SUN5I_AHB_REG);
> +
> +       sunxi_ccu_probe(node, reg, &sun5i_a10s_ccu_desc);
> +}
> +CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
> +              sun5i_a10s_ccu_setup);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
> new file mode 100644
> index 000000000000..43f2ce3e9e6e
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
> @@ -0,0 +1,129 @@
> +/*
> + * Copyright 2016 Maxime Ripard
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _CCU_SUN5I_H_
> +#define _CCU_SUN5I_H_
> +
> +#include <dt-bindings/clock/sun5i-ccu.h>
> +#include <dt-bindings/reset/sun5i-ccu.h>
> +
> +#define CLK_HOSC               1
> +#define CLK_OSC3M              2
> +#define CLK_PLL_CORE           3
> +#define CLK_PLL_AUDIO_BASE     4
> +#define CLK_PLL_AUDIO          5
> +#define CLK_PLL_AUDIO_2X       6
> +#define CLK_PLL_AUDIO_4X       7
> +#define CLK_PLL_AUDIO_8X       8
> +#define CLK_PLL_VIDEO0         9
> +#define CLK_PLL_VIDEO0_2X      10
> +#define CLK_PLL_VE             11
> +#define CLK_PLL_DDR_BASE       12
> +#define CLK_PLL_DDR            13
> +#define CLK_PLL_DDR_OTHER      14
> +#define CLK_PLL_PERIPH         15
> +#define CLK_PLL_VIDEO1         16
> +#define CLK_PLL_VIDEO1_2X      17
> +#define CLK_OSC24M             18
> +#define CLK_CPU                        19
> +#define CLK_AXI                        20
> +#define CLK_AHB                        21
> +#define CLK_APB0               22
> +#define CLK_APB1               23
> +#define CLK_DRAM_AXI           24
> +#define CLK_AHB_OTG            25
> +#define CLK_AHB_EHCI           26
> +#define CLK_AHB_OHCI           27
> +#define CLK_AHB_SS             28
> +#define CLK_AHB_DMA            29
> +#define CLK_AHB_BIST           30
> +#define CLK_AHB_MMC0           31
> +#define CLK_AHB_MMC1           32
> +#define CLK_AHB_MMC2           33
> +#define CLK_AHB_NAND           34
> +#define CLK_AHB_SDRAM          35
> +#define CLK_AHB_EMAC           36
> +#define CLK_AHB_TS             37
> +#define CLK_AHB_SPI0           38
> +#define CLK_AHB_SPI1           39
> +#define CLK_AHB_SPI2           40
> +#define CLK_AHB_GPS            41
> +#define CLK_AHB_HSTIMER                42
> +#define CLK_AHB_VE             43
> +#define CLK_AHB_TVE            44
> +#define CLK_AHB_LCD            45
> +#define CLK_AHB_CSI            46
> +#define CLK_AHB_HDMI           47
> +#define CLK_AHB_DE_BE          48
> +#define CLK_AHB_DE_FE          49
> +#define CLK_AHB_IEP            50
> +#define CLK_AHB_GPU            51
> +#define CLK_APB0_CODEC         52
> +#define CLK_APB0_SPDIF         53
> +#define CLK_APB0_I2S           54
> +#define CLK_APB0_PIO           55
> +#define CLK_APB0_IR            56
> +#define CLK_APB0_KEYPAD                57
> +#define CLK_APB1_I2C0          58
> +#define CLK_APB1_I2C1          59
> +#define CLK_APB1_I2C2          60
> +#define CLK_APB1_UART0         61
> +#define CLK_APB1_UART1         62
> +#define CLK_APB1_UART2         63
> +#define CLK_APB1_UART3         64
> +#define CLK_NAND               65
> +#define CLK_MMC0               66
> +#define CLK_MMC1               67
> +#define CLK_MMC2               68
> +#define CLK_TS                 69
> +#define CLK_SS                 70
> +#define CLK_CE                 71
> +#define CLK_SPI0               72
> +#define CLK_SPI1               73
> +#define CLK_SPI2               74
> +#define CLK_IR                 75
> +#define CLK_I2S                        76
> +#define CLK_SPDIF              77
> +#define CLK_KEYPAD             78
> +#define CLK_USB_OHCI           79
> +#define CLK_USB_PHY0           80
> +#define CLK_USB_PHY1           81
> +#define CLK_GPS                        82
> +#define CLK_DRAM_VE            83
> +#define CLK_DRAM_CSI           84
> +#define CLK_DRAM_TS            85
> +#define CLK_DRAM_TVE           86
> +#define CLK_DRAM_DE_FE         87
> +#define CLK_DRAM_DE_BE         88
> +#define CLK_DRAM_ACE           89
> +#define CLK_DRAM_IEP           90
> +#define CLK_DE_BE              91
> +#define CLK_DE_FE              92
> +#define CLK_TCON_CH0           93
> +#define CLK_TCON_CH1_SCLK      94
> +#define CLK_TCON_CH1           95
> +#define CLK_CSI                        96
> +#define CLK_VE                 97
> +#define CLK_CODEC              98
> +#define CLK_AVS                        99
> +#define CLK_HDMI               100
> +#define CLK_GPU                        101
> +#define CLK_MBUS               102
> +#define CLK_IEP                        103
> +
> +#define CLK_NUMBER             (CLK_IEP + 1)
> +
> +#endif /* _CCU_SUN5I_H_ */

Didn't you already list all the clocks in the device tree bindings header
patch 5?


Regards
ChenYu

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

* Re: [PATCH 7/10] clk: sunxi-ng: Add A13 CCU driver
  2016-11-08 17:23 ` [PATCH 7/10] clk: sunxi-ng: Add A13 " Maxime Ripard
@ 2016-11-13  9:55   ` Chen-Yu Tsai
  0 siblings, 0 replies; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13  9:55 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig         |  10 +-
>  drivers/clk/sunxi-ng/Makefile        |   1 +-
>  drivers/clk/sunxi-ng/ccu-sun5i-a13.c | 681 ++++++++++++++++++++++++++++-
>  3 files changed, 692 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a13.c

I'm not sure what to make of this one. Presumably this is the same as the A10s,
with some bits (TS, HDMI, I2S, GPS) removed. BTW you kept the GPS reset control
in this one.

Hans and others have said and IIRC proven that the sun5i is the same die, with
some exposing more peripherals than others. Wouldn't it make sense to use the
same CCU driver for all of them? It's not like Allwinner actually disabled the
clock control or hardware block.

If you don't like it, perhaps you can share the same set of definitions, but
have separate lists of what clocks are registered, for each SoC variant. That
would at least cut down on code size and the effort to maintain 3 copies of
almost the exact same thing.

I guess the same applies to the GR8 CCU driver patch. And the comments from
the previous (A10s CCU driver) patch applies to both.

Let me know what you think.


Regards
ChenYu

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

* Re: [PATCH 9/10] ARM: sun5i: Convert to CCU
  2016-11-08 17:23 ` [PATCH 9/10] ARM: sun5i: Convert to CCU Maxime Ripard
@ 2016-11-13 15:01   ` Chen-Yu Tsai
  2016-11-21 22:04     ` Maxime Ripard
  0 siblings, 1 reply; 23+ messages in thread
From: Chen-Yu Tsai @ 2016-11-13 15:01 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mike Turquette, Stephen Boyd, Chen-Yu Tsai, linux-arm-kernel,
	linux-kernel, linux-clk

On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Now that we have drivers for all of them, convert all the SoCs that share
> the sun5i DTSI to the new CCU driver.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  arch/arm/boot/dts/sun5i-a10s.dtsi |  94 +-------
>  arch/arm/boot/dts/sun5i-a13.dtsi  | 140 +-----------
>  arch/arm/boot/dts/sun5i-r8.dtsi   |  10 +-
>  arch/arm/boot/dts/sun5i.dtsi      | 368 ++++---------------------------
>  4 files changed, 90 insertions(+), 522 deletions(-)
>
> diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
> index 7aa8c7aa0153..1d26ae7267dc 100644
> --- a/arch/arm/boot/dts/sun5i-a10s.dtsi
> +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
> @@ -61,99 +61,33 @@
>                 #size-cells = <1>;
>                 ranges;
>
> -               framebuffer@0 {
> -                       compatible = "allwinner,simple-framebuffer",
> -                                    "simple-framebuffer";
> -                       allwinner,pipeline = "de_be0-lcd0-hdmi";
> -                       clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
> -                                <&ahb_gates 43>, <&ahb_gates 44>;
> -                       status = "disabled";
> -               };
> -
>                 framebuffer@1 {
>                         compatible = "allwinner,simple-framebuffer",
>                                      "simple-framebuffer";
> -                       allwinner,pipeline = "de_be0-lcd0";
> -                       clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
> -                                <&ahb_gates 44>;
> +                       allwinner,pipeline = "de_be0-lcd0-tve0";
> +                       clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
> +                                <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
> +                                <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
>                         status = "disabled";
>                 };
>
>                 framebuffer@2 {
>                         compatible = "allwinner,simple-framebuffer",
>                                      "simple-framebuffer";
> -                       allwinner,pipeline = "de_be0-lcd0-tve0";
> -                       clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>,
> -                                <&ahb_gates 36>, <&ahb_gates 44>;
> +                       allwinner,pipeline = "de_be0-lcd0-hdmi";
> +                       clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_HDMI>,
> +                                <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DRAM_DE_BE>,
> +                                <&ccu CLK_DE_BE>, <&ccu CLK_HDMI>;

You might want to mention you moved the framebuffer nodes around.
Or maybe do it in a separate patch.

>                         status = "disabled";
>                 };
>         };
>
> -       clocks {
> -               ahb_gates: clk@01c20060 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
> -                       reg = <0x01c20060 0x8>;
> -                       clocks = <&ahb>;
> -                       clock-indices = <0>, <1>,
> -                                       <2>, <5>, <6>,
> -                                       <7>, <8>, <9>,
> -                                       <10>, <13>,
> -                                       <14>, <17>, <18>,
> -                                       <20>, <21>, <22>,
> -                                       <26>, <28>, <32>,
> -                                       <34>, <36>, <40>,
> -                                       <43>, <44>,
> -                                       <46>, <51>,
> -                                       <52>;
> -                       clock-output-names = "ahb_usbotg", "ahb_ehci",
> -                                            "ahb_ohci", "ahb_ss", "ahb_dma",
> -                                            "ahb_bist", "ahb_mmc0", "ahb_mmc1",
> -                                            "ahb_mmc2", "ahb_nand",
> -                                            "ahb_sdram", "ahb_emac", "ahb_ts",
> -                                            "ahb_spi0", "ahb_spi1", "ahb_spi2",
> -                                            "ahb_gps", "ahb_stimer", "ahb_ve",
> -                                            "ahb_tve", "ahb_lcd", "ahb_csi",
> -                                            "ahb_hdmi", "ahb_de_be",
> -                                            "ahb_de_fe", "ahb_iep",
> -                                            "ahb_mali400";
> -               };
> -
> -               apb0_gates: clk@01c20068 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
> -                       reg = <0x01c20068 0x4>;
> -                       clocks = <&apb0>;
> -                       clock-indices = <0>, <3>,
> -                                       <5>, <6>,
> -                                       <10>;
> -                       clock-output-names = "apb0_codec", "apb0_iis",
> -                                            "apb0_pio", "apb0_ir",
> -                                            "apb0_keypad";
> -               };
> -
> -               apb1_gates: clk@01c2006c {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
> -                       reg = <0x01c2006c 0x4>;
> -                       clocks = <&apb1>;
> -                       clock-indices = <0>, <1>,
> -                                       <2>, <16>,
> -                                       <17>, <18>,
> -                                       <19>;
> -                       clock-output-names = "apb1_i2c0", "apb1_i2c1",
> -                                            "apb1_i2c2", "apb1_uart0",
> -                                            "apb1_uart1", "apb1_uart2",
> -                                            "apb1_uart3";
> -               };
> -       };
> -
>         soc@01c00000 {
>                 emac: ethernet@01c0b000 {
>                         compatible = "allwinner,sun4i-a10-emac";
>                         reg = <0x01c0b000 0x1000>;
>                         interrupts = <55>;
> -                       clocks = <&ahb_gates 17>;
> +                       clocks = <&ccu CLK_AHB_EMAC>;
>                         allwinner,sram = <&emac_sram 1>;
>                         status = "disabled";
>                 };
> @@ -169,7 +103,7 @@
>                 pwm: pwm@01c20e00 {
>                         compatible = "allwinner,sun5i-a10s-pwm";
>                         reg = <0x01c20e00 0xc>;
> -                       clocks = <&osc24M>;
> +                       clocks = <&ccu CLK_HOSC>;
>                         #pwm-cells = <3>;
>                         status = "disabled";
>                 };
> @@ -180,7 +114,7 @@
>                         interrupts = <1>;
>                         reg-shift = <2>;
>                         reg-io-width = <4>;
> -                       clocks = <&apb1_gates 16>;
> +                       clocks = <&ccu CLK_APB1_UART0>;
>                         status = "disabled";
>                 };
>
> @@ -190,12 +124,16 @@
>                         interrupts = <3>;
>                         reg-shift = <2>;
>                         reg-io-width = <4>;
> -                       clocks = <&apb1_gates 18>;
> +                       clocks = <&ccu CLK_APB1_UART2>;
>                         status = "disabled";
>                 };
>         };
>  };
>
> +&ccu {
> +       compatible = "allwinner,sun5i-a10s-ccu";
> +};
> +
>  &pio {
>         compatible = "allwinner,sun5i-a10s-pinctrl";
>
> diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
> index a17ba0243db3..0330304f1d42 100644
> --- a/arch/arm/boot/dts/sun5i-a13.dtsi
> +++ b/arch/arm/boot/dts/sun5i-a13.dtsi
> @@ -61,8 +61,8 @@
>                         compatible = "allwinner,simple-framebuffer",
>                                      "simple-framebuffer";
>                         allwinner,pipeline = "de_be0-lcd0";
> -                       clocks = <&ahb_gates 36>, <&ahb_gates 44>, <&de_be_clk>,
> -                                <&tcon_ch0_clk>, <&dram_gates 26>;
> +                       clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
> +                                <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
>                         status = "disabled";
>                 };
>         };
> @@ -99,114 +99,6 @@
>                 };
>         };
>
> -       clocks {
> -               ahb_gates: clk@01c20060 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-ahb-gates-clk";
> -                       reg = <0x01c20060 0x8>;
> -                       clocks = <&ahb>;
> -                       clock-indices = <0>, <1>,
> -                                       <2>, <5>, <6>,
> -                                       <7>, <8>, <9>,
> -                                       <10>, <13>,
> -                                       <14>, <20>,
> -                                       <21>, <22>,
> -                                       <28>, <32>, <34>,
> -                                       <36>, <40>, <44>,
> -                                       <46>, <51>,
> -                                       <52>;
> -                       clock-output-names = "ahb_usbotg", "ahb_ehci",
> -                                            "ahb_ohci", "ahb_ss", "ahb_dma",
> -                                            "ahb_bist", "ahb_mmc0", "ahb_mmc1",
> -                                            "ahb_mmc2", "ahb_nand",
> -                                            "ahb_sdram", "ahb_spi0",
> -                                            "ahb_spi1", "ahb_spi2",
> -                                            "ahb_stimer", "ahb_ve", "ahb_tve",
> -                                            "ahb_lcd", "ahb_csi", "ahb_de_be",
> -                                            "ahb_de_fe", "ahb_iep",
> -                                            "ahb_mali400";
> -               };
> -
> -               apb0_gates: clk@01c20068 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-apb0-gates-clk";
> -                       reg = <0x01c20068 0x4>;
> -                       clocks = <&apb0>;
> -                       clock-indices = <0>, <5>,
> -                                       <6>;
> -                       clock-output-names = "apb0_codec", "apb0_pio",
> -                                            "apb0_ir";
> -               };
> -
> -               apb1_gates: clk@01c2006c {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-apb1-gates-clk";
> -                       reg = <0x01c2006c 0x4>;
> -                       clocks = <&apb1>;
> -                       clock-indices = <0>, <1>,
> -                                       <2>, <17>,
> -                                       <19>;
> -                       clock-output-names = "apb1_i2c0", "apb1_i2c1",
> -                                            "apb1_i2c2", "apb1_uart1",
> -                                            "apb1_uart3";
> -               };
> -
> -               dram_gates: clk@01c20100 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-dram-gates-clk",
> -                                    "allwinner,sun4i-a10-gates-clk";
> -                       reg = <0x01c20100 0x4>;
> -                       clocks = <&pll5 0>;
> -                       clock-indices = <0>,
> -                                       <1>,
> -                                       <25>,
> -                                       <26>,
> -                                       <29>,
> -                                       <31>;
> -                       clock-output-names = "dram_ve",
> -                                            "dram_csi",
> -                                            "dram_de_fe",
> -                                            "dram_de_be",
> -                                            "dram_ace",
> -                                            "dram_iep";
> -               };
> -
> -               de_be_clk: clk@01c20104 {
> -                       #clock-cells = <0>;
> -                       #reset-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-display-clk";
> -                       reg = <0x01c20104 0x4>;
> -                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
> -                       clock-output-names = "de-be";
> -               };
> -
> -               de_fe_clk: clk@01c2010c {
> -                       #clock-cells = <0>;
> -                       #reset-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-display-clk";
> -                       reg = <0x01c2010c 0x4>;
> -                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
> -                       clock-output-names = "de-fe";
> -               };
> -
> -               tcon_ch0_clk: clk@01c20118 {
> -                       #clock-cells = <0>;
> -                       #reset-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
> -                       reg = <0x01c20118 0x4>;
> -                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
> -                       clock-output-names = "tcon-ch0-sclk";
> -               };
> -
> -               tcon_ch1_clk: clk@01c2012c {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
> -                       reg = <0x01c2012c 0x4>;
> -                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
> -                       clock-output-names = "tcon-ch1-sclk";
> -               };
> -       };
> -
>         display-engine {
>                 compatible = "allwinner,sun5i-a13-display-engine";
>                 allwinner,pipelines = <&fe0>;
> @@ -217,11 +109,11 @@
>                         compatible = "allwinner,sun5i-a13-tcon";
>                         reg = <0x01c0c000 0x1000>;
>                         interrupts = <44>;
> -                       resets = <&tcon_ch0_clk 1>;
> +                       resets = <&ccu RST_LCD>;
>                         reset-names = "lcd";
> -                       clocks = <&ahb_gates 36>,
> -                                <&tcon_ch0_clk>,
> -                                <&tcon_ch1_clk>;
> +                       clocks = <&ccu CLK_AHB_LCD>,
> +                                <&ccu CLK_TCON_CH0>,
> +                                <&ccu CLK_TCON_CH1>;

Just curious, is CLK_TCON_CH1_SCLK ever used?

>                         clock-names = "ahb",
>                                       "tcon-ch0",
>                                       "tcon-ch1";
> @@ -254,7 +146,7 @@
>                 pwm: pwm@01c20e00 {
>                         compatible = "allwinner,sun5i-a13-pwm";
>                         reg = <0x01c20e00 0xc>;
> -                       clocks = <&osc24M>;
> +                       clocks = <&ccu CLK_HOSC>;
>                         #pwm-cells = <3>;
>                         status = "disabled";
>                 };
> @@ -263,11 +155,11 @@
>                         compatible = "allwinner,sun5i-a13-display-frontend";
>                         reg = <0x01e00000 0x20000>;
>                         interrupts = <47>;
> -                       clocks = <&ahb_gates 46>, <&de_fe_clk>,
> -                                <&dram_gates 25>;
> +                       clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>,
> +                                <&ccu CLK_DRAM_DE_FE>;
>                         clock-names = "ahb", "mod",
>                                       "ram";
> -                       resets = <&de_fe_clk>;
> +                       resets = <&ccu RST_DE_FE>;
>                         status = "disabled";
>
>                         ports {
> @@ -290,14 +182,14 @@
>                 be0: display-backend@01e60000 {
>                         compatible = "allwinner,sun5i-a13-display-backend";
>                         reg = <0x01e60000 0x10000>;
> -                       clocks = <&ahb_gates 44>, <&de_be_clk>,
> -                                <&dram_gates 26>;
> +                       clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
> +                                <&ccu CLK_DRAM_DE_BE>;
>                         clock-names = "ahb", "mod",
>                                       "ram";
> -                       resets = <&de_be_clk>;
> +                       resets = <&ccu RST_DE_BE>;
>                         status = "disabled";
>
> -                       assigned-clocks = <&de_be_clk>;
> +                       assigned-clocks = <&ccu CLK_DE_BE>;
>                         assigned-clock-rates = <300000000>;
>
>                         ports {
> @@ -330,6 +222,10 @@
>         };
>  };
>
> +&ccu {
> +       compatible = "allwinner,sun5i-a13-ccu";
> +};
> +
>  &cpu0 {
>         clock-latency = <244144>; /* 8 32k periods */
>         operating-points = <
> diff --git a/arch/arm/boot/dts/sun5i-r8.dtsi b/arch/arm/boot/dts/sun5i-r8.dtsi
> index 8b058f53b7dc..4c1141396c99 100644
> --- a/arch/arm/boot/dts/sun5i-r8.dtsi
> +++ b/arch/arm/boot/dts/sun5i-r8.dtsi
> @@ -51,9 +51,9 @@
>                         compatible = "allwinner,simple-framebuffer",
>                                      "simple-framebuffer";
>                         allwinner,pipeline = "de_be0-lcd0-tve0";
> -                       clocks = <&ahb_gates 34>, <&ahb_gates 36>,
> -                                <&ahb_gates 44>, <&de_be_clk>,
> -                                <&tcon_ch1_clk>, <&dram_gates 26>;
> +                       clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
> +                                <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
> +                                <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
>                         status = "disabled";
>                 };
>         };
> @@ -62,8 +62,8 @@
>                 tve0: tv-encoder@01c0a000 {
>                         compatible = "allwinner,sun4i-a10-tv-encoder";
>                         reg = <0x01c0a000 0x1000>;
> -                       clocks = <&ahb_gates 34>;
> -                       resets = <&tcon_ch0_clk 0>;
> +                       clocks = <&ccu CLK_AHB_TVE>;
> +                       resets = <&ccu RST_TVE>;
>                         status = "disabled";
>
>                         port {
> diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
> index b4ccee8cfb02..2dbc7623ec04 100644
> --- a/arch/arm/boot/dts/sun5i.dtsi
> +++ b/arch/arm/boot/dts/sun5i.dtsi
> @@ -44,13 +44,29 @@
>
>  #include "skeleton.dtsi"
>
> -#include <dt-bindings/clock/sun4i-a10-pll2.h>
> +#include <dt-bindings/clock/sun5i-ccu.h>
>  #include <dt-bindings/dma/sun4i-a10.h>
>  #include <dt-bindings/pinctrl/sun4i-a10.h>
> +#include <dt-bindings/reset/sun5i-ccu.h>
>
>  / {
>         interrupt-parent = <&intc>;
>
> +       chosen {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               framebuffer@0 {
> +                       compatible = "allwinner,simple-framebuffer",
> +                                    "simple-framebuffer";
> +                       allwinner,pipeline = "de_be0-lcd0";
> +                       clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
> +                                <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
> +                       status = "disabled";
> +               };
> +       };
> +
>         cpus {
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> @@ -59,7 +75,7 @@
>                         device_type = "cpu";
>                         compatible = "arm,cortex-a8";
>                         reg = <0x0>;
> -                       clocks = <&cpu>;
> +                       clocks = <&ccu CLK_CPU>;
>                 };
>         };
>
> @@ -68,291 +84,19 @@
>                 #size-cells = <1>;
>                 ranges;
>
> -               /*
> -                * This is a dummy clock, to be used as placeholder on
> -                * other mux clocks when a specific parent clock is not
> -                * yet implemented. It should be dropped when the driver
> -                * is complete.
> -                */
> -               dummy: dummy {
> -                       #clock-cells = <0>;
> -                       compatible = "fixed-clock";
> -                       clock-frequency = <0>;
> -               };
> -
>                 osc24M: clk@01c20050 {
>                         #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-osc-clk";
> -                       reg = <0x01c20050 0x4>;
> +                       compatible = "fixed-clock";
>                         clock-frequency = <24000000>;
>                         clock-output-names = "osc24M";
>                 };
>
> -               osc3M: osc3M_clk {
> -                       compatible = "fixed-factor-clock";
> -                       #clock-cells = <0>;
> -                       clock-div = <8>;
> -                       clock-mult = <1>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "osc3M";
> -               };
> -
>                 osc32k: clk@0 {
>                         #clock-cells = <0>;
>                         compatible = "fixed-clock";
>                         clock-frequency = <32768>;
>                         clock-output-names = "osc32k";
>                 };
> -
> -               pll1: clk@01c20000 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-pll1-clk";
> -                       reg = <0x01c20000 0x4>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "pll1";
> -               };
> -
> -               pll2: clk@01c20008 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-pll2-clk";
> -                       reg = <0x01c20008 0x8>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "pll2-1x", "pll2-2x",
> -                                            "pll2-4x", "pll2-8x";
> -               };
> -
> -               pll3: clk@01c20010 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-pll3-clk";
> -                       reg = <0x01c20010 0x4>;
> -                       clocks = <&osc3M>;
> -                       clock-output-names = "pll3";
> -               };
> -
> -               pll3x2: pll3x2_clk {
> -                       compatible = "allwinner,sun4i-a10-pll3-2x-clk", "fixed-factor-clock";
> -                       #clock-cells = <0>;
> -                       clock-div = <1>;
> -                       clock-mult = <2>;
> -                       clocks = <&pll3>;
> -                       clock-output-names = "pll3-2x";
> -               };
> -
> -               pll4: clk@01c20018 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-pll1-clk";
> -                       reg = <0x01c20018 0x4>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "pll4";
> -               };
> -
> -               pll5: clk@01c20020 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-pll5-clk";
> -                       reg = <0x01c20020 0x4>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "pll5_ddr", "pll5_other";
> -               };
> -
> -               pll6: clk@01c20028 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-pll6-clk";
> -                       reg = <0x01c20028 0x4>;
> -                       clocks = <&osc24M>;
> -                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
> -               };
> -
> -               pll7: clk@01c20030 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-pll3-clk";
> -                       reg = <0x01c20030 0x4>;
> -                       clocks = <&osc3M>;
> -                       clock-output-names = "pll7";
> -               };
> -
> -               pll7x2: pll7x2_clk {
> -                       compatible = "fixed-factor-clock";
> -                       #clock-cells = <0>;
> -                       clock-div = <1>;
> -                       clock-mult = <2>;
> -                       clocks = <&pll7>;
> -                       clock-output-names = "pll7-2x";
> -               };
> -
> -               /* dummy is 200M */
> -               cpu: cpu@01c20054 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-cpu-clk";
> -                       reg = <0x01c20054 0x4>;
> -                       clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
> -                       clock-output-names = "cpu";
> -               };
> -
> -               axi: axi@01c20054 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-axi-clk";
> -                       reg = <0x01c20054 0x4>;
> -                       clocks = <&cpu>;
> -                       clock-output-names = "axi";
> -               };
> -
> -               ahb: ahb@01c20054 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun5i-a13-ahb-clk";
> -                       reg = <0x01c20054 0x4>;
> -                       clocks = <&axi>, <&cpu>, <&pll6 1>;
> -                       clock-output-names = "ahb";
> -                       /*
> -                        * Use PLL6 as parent, instead of CPU/AXI
> -                        * which has rate changes due to cpufreq
> -                        */
> -                       assigned-clocks = <&ahb>;
> -                       assigned-clock-parents = <&pll6 1>;
> -               };
> -
> -               apb0: apb0@01c20054 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-apb0-clk";
> -                       reg = <0x01c20054 0x4>;
> -                       clocks = <&ahb>;
> -                       clock-output-names = "apb0";
> -               };
> -
> -               apb1: clk@01c20058 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-apb1-clk";
> -                       reg = <0x01c20058 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
> -                       clock-output-names = "apb1";
> -               };
> -
> -               axi_gates: clk@01c2005c {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-axi-gates-clk";
> -                       reg = <0x01c2005c 0x4>;
> -                       clocks = <&axi>;
> -                       clock-indices = <0>;
> -                       clock-output-names = "axi_dram";
> -               };
> -
> -               nand_clk: clk@01c20080 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c20080 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "nand";
> -               };
> -
> -               ms_clk: clk@01c20084 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c20084 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "ms";
> -               };
> -
> -               mmc0_clk: clk@01c20088 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-mmc-clk";
> -                       reg = <0x01c20088 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "mmc0",
> -                                            "mmc0_output",
> -                                            "mmc0_sample";
> -               };
> -
> -               mmc1_clk: clk@01c2008c {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-mmc-clk";
> -                       reg = <0x01c2008c 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "mmc1",
> -                                            "mmc1_output",
> -                                            "mmc1_sample";
> -               };
> -
> -               mmc2_clk: clk@01c20090 {
> -                       #clock-cells = <1>;
> -                       compatible = "allwinner,sun4i-a10-mmc-clk";
> -                       reg = <0x01c20090 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "mmc2",
> -                                            "mmc2_output",
> -                                            "mmc2_sample";
> -               };
> -
> -               ts_clk: clk@01c20098 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c20098 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "ts";
> -               };
> -
> -               ss_clk: clk@01c2009c {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c2009c 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "ss";
> -               };
> -
> -               spi0_clk: clk@01c200a0 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c200a0 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "spi0";
> -               };
> -
> -               spi1_clk: clk@01c200a4 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c200a4 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "spi1";
> -               };
> -
> -               spi2_clk: clk@01c200a8 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c200a8 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "spi2";
> -               };
> -
> -               ir0_clk: clk@01c200b0 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-mod0-clk";
> -                       reg = <0x01c200b0 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "ir0";
> -               };
> -
> -               usb_clk: clk@01c200cc {
> -                       #clock-cells = <1>;
> -                       #reset-cells = <1>;
> -                       compatible = "allwinner,sun5i-a13-usb-clk";
> -                       reg = <0x01c200cc 0x4>;
> -                       clocks = <&pll6 1>;
> -                       clock-output-names = "usb_ohci0", "usb_phy";
> -               };
> -
> -               codec_clk: clk@01c20140 {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun4i-a10-codec-clk";
> -                       reg = <0x01c20140 0x4>;
> -                       clocks = <&pll2 SUN4I_A10_PLL2_1X>;
> -                       clock-output-names = "codec";
> -               };
> -
> -               mbus_clk: clk@01c2015c {
> -                       #clock-cells = <0>;
> -                       compatible = "allwinner,sun5i-a13-mbus-clk";
> -                       reg = <0x01c2015c 0x4>;
> -                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> -                       clock-output-names = "mbus";
> -               };
>         };
>
>         soc@01c00000 {
> @@ -395,7 +139,7 @@
>                         compatible = "allwinner,sun4i-a10-dma";
>                         reg = <0x01c02000 0x1000>;
>                         interrupts = <27>;
> -                       clocks = <&ahb_gates 6>;
> +                       clocks = <&ccu CLK_AHB_DMA>;
>                         #dma-cells = <2>;
>                 };
>
> @@ -403,7 +147,7 @@
>                         compatible = "allwinner,sun4i-a10-spi";
>                         reg = <0x01c05000 0x1000>;
>                         interrupts = <10>;
> -                       clocks = <&ahb_gates 20>, <&spi0_clk>;
> +                       clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
>                         clock-names = "ahb", "mod";
>                         dmas = <&dma SUN4I_DMA_DEDICATED 27>,
>                                <&dma SUN4I_DMA_DEDICATED 26>;
> @@ -417,7 +161,7 @@
>                         compatible = "allwinner,sun4i-a10-spi";
>                         reg = <0x01c06000 0x1000>;
>                         interrupts = <11>;
> -                       clocks = <&ahb_gates 21>, <&spi1_clk>;
> +                       clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
>                         clock-names = "ahb", "mod";
>                         dmas = <&dma SUN4I_DMA_DEDICATED 9>,
>                                <&dma SUN4I_DMA_DEDICATED 8>;
> @@ -430,14 +174,8 @@
>                 mmc0: mmc@01c0f000 {
>                         compatible = "allwinner,sun5i-a13-mmc";
>                         reg = <0x01c0f000 0x1000>;
> -                       clocks = <&ahb_gates 8>,
> -                                <&mmc0_clk 0>,
> -                                <&mmc0_clk 1>,
> -                                <&mmc0_clk 2>;
> -                       clock-names = "ahb",
> -                                     "mmc",
> -                                     "output",
> -                                     "sample";
> +                       clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
> +                       clock-names = "ahb", "mmc";
>                         interrupts = <32>;
>                         status = "disabled";
>                         #address-cells = <1>;
> @@ -447,14 +185,8 @@
>                 mmc1: mmc@01c10000 {
>                         compatible = "allwinner,sun5i-a13-mmc";
>                         reg = <0x01c10000 0x1000>;
> -                       clocks = <&ahb_gates 9>,
> -                                <&mmc1_clk 0>,
> -                                <&mmc1_clk 1>,
> -                                <&mmc1_clk 2>;
> -                       clock-names = "ahb",
> -                                     "mmc",
> -                                     "output",
> -                                     "sample";
> +                       clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
> +                       clock-names = "ahb", "mmc";
>                         interrupts = <33>;
>                         status = "disabled";
>                         #address-cells = <1>;
> @@ -464,14 +196,8 @@
>                 mmc2: mmc@01c11000 {
>                         compatible = "allwinner,sun5i-a13-mmc";
>                         reg = <0x01c11000 0x1000>;
> -                       clocks = <&ahb_gates 10>,
> -                                <&mmc2_clk 0>,
> -                                <&mmc2_clk 1>,
> -                                <&mmc2_clk 2>;
> -                       clock-names = "ahb",
> -                                     "mmc",
> -                                     "output",
> -                                     "sample";
> +                       clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
> +                       clock-names = "ahb", "mmc";
>                         interrupts = <34>;
>                         status = "disabled";
>                         #address-cells = <1>;
> @@ -481,7 +207,7 @@
>                 usb_otg: usb@01c13000 {
>                         compatible = "allwinner,sun4i-a10-musb";
>                         reg = <0x01c13000 0x0400>;
> -                       clocks = <&ahb_gates 0>;
> +                       clocks = <&ccu CLK_AHB_OTG>;
>                         interrupts = <38>;
>                         interrupt-names = "mc";
>                         phys = <&usbphy 0>;
> @@ -496,9 +222,9 @@
>                         compatible = "allwinner,sun5i-a13-usb-phy";
>                         reg = <0x01c13400 0x10 0x01c14800 0x4>;
>                         reg-names = "phy_ctrl", "pmu1";
> -                       clocks = <&usb_clk 8>;
> +                       clocks = <&ccu CLK_USB_PHY0>;
>                         clock-names = "usb_phy";
> -                       resets = <&usb_clk 0>, <&usb_clk 1>;
> +                       resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
>                         reset-names = "usb0_reset", "usb1_reset";
>                         status = "disabled";
>                 };
> @@ -507,7 +233,7 @@
>                         compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
>                         reg = <0x01c14000 0x100>;
>                         interrupts = <39>;
> -                       clocks = <&ahb_gates 1>;
> +                       clocks = <&ccu CLK_AHB_EHCI>;
>                         phys = <&usbphy 1>;
>                         phy-names = "usb";
>                         status = "disabled";
> @@ -517,7 +243,7 @@
>                         compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
>                         reg = <0x01c14400 0x100>;
>                         interrupts = <40>;
> -                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
> +                       clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
>                         phys = <&usbphy 1>;
>                         phy-names = "usb";
>                         status = "disabled";
> @@ -527,7 +253,7 @@
>                         compatible = "allwinner,sun4i-a10-spi";
>                         reg = <0x01c17000 0x1000>;
>                         interrupts = <12>;
> -                       clocks = <&ahb_gates 22>, <&spi2_clk>;
> +                       clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
>                         clock-names = "ahb", "mod";
>                         dmas = <&dma SUN4I_DMA_DEDICATED 29>,
>                                <&dma SUN4I_DMA_DEDICATED 28>;
> @@ -537,6 +263,14 @@
>                         #size-cells = <0>;
>                 };
>
> +               ccu: clock@01c20000 {
> +                       reg = <0x01c20000 0x400>;
> +                       clocks = <&osc24M>, <&osc32k>;
> +                       clock-names = "hosc", "losc";
> +                       #clock-cells = <1>;
> +                       #reset-cells = <1>;
> +               };
> +
>                 intc: interrupt-controller@01c20400 {
>                         compatible = "allwinner,sun4i-a10-ic";
>                         reg = <0x01c20400 0x400>;
> @@ -547,7 +281,7 @@
>                 pio: pinctrl@01c20800 {
>                         reg = <0x01c20800 0x400>;
>                         interrupts = <28>;
> -                       clocks = <&apb0_gates 5>;
> +                       clocks = <&ccu CLK_APB0_PIO>;
>                         gpio-controller;
>                         interrupt-controller;
>                         #interrupt-cells = <3>;
> @@ -641,7 +375,7 @@
>                         compatible = "allwinner,sun4i-a10-timer";
>                         reg = <0x01c20c00 0x90>;
>                         interrupts = <22>;
> -                       clocks = <&osc24M>;
> +                       clocks = <&ccu CLK_HOSC>;
>                 };
>
>                 wdt: watchdog@01c20c90 {
> @@ -661,7 +395,7 @@
>                         compatible = "allwinner,sun4i-a10-codec";
>                         reg = <0x01c22c00 0x40>;
>                         interrupts = <30>;
> -                       clocks = <&apb0_gates 0>, <&codec_clk>;
> +                       clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
>                         clock-names = "apb", "codec";
>                         dmas = <&dma SUN4I_DMA_NORMAL 19>,
>                                <&dma SUN4I_DMA_NORMAL 19>;
> @@ -687,7 +421,7 @@
>                         interrupts = <2>;
>                         reg-shift = <2>;
>                         reg-io-width = <4>;
> -                       clocks = <&apb1_gates 17>;
> +                       clocks = <&ccu CLK_APB1_UART1>;
>                         status = "disabled";
>                 };
>
> @@ -697,7 +431,7 @@
>                         interrupts = <4>;
>                         reg-shift = <2>;
>                         reg-io-width = <4>;
> -                       clocks = <&apb1_gates 19>;
> +                       clocks = <&ccu CLK_APB1_UART3>;
>                         status = "disabled";
>                 };
>
> @@ -705,7 +439,7 @@
>                         compatible = "allwinner,sun4i-a10-i2c";
>                         reg = <0x01c2ac00 0x400>;
>                         interrupts = <7>;
> -                       clocks = <&apb1_gates 0>;
> +                       clocks = <&ccu CLK_APB1_I2C0>;
>                         status = "disabled";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> @@ -715,7 +449,7 @@
>                         compatible = "allwinner,sun4i-a10-i2c";
>                         reg = <0x01c2b000 0x400>;
>                         interrupts = <8>;
> -                       clocks = <&apb1_gates 1>;
> +                       clocks = <&ccu CLK_APB1_I2C1>;
>                         status = "disabled";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> @@ -725,7 +459,7 @@
>                         compatible = "allwinner,sun4i-a10-i2c";
>                         reg = <0x01c2b400 0x400>;
>                         interrupts = <9>;
> -                       clocks = <&apb1_gates 2>;
> +                       clocks = <&ccu CLK_APB1_I2C2>;
>                         status = "disabled";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> @@ -735,7 +469,7 @@
>                         compatible = "allwinner,sun5i-a13-hstimer";
>                         reg = <0x01c60000 0x1000>;
>                         interrupts = <82>, <83>;
> -                       clocks = <&ahb_gates 28>;
> +                       clocks = <&ccu CLK_AHB_HSTIMER>;
>                 };
>         };
>  };

The rest looks good.

ChenYu

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

* Re: [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver
  2016-11-13  9:34   ` Chen-Yu Tsai
@ 2016-11-21 21:45     ` Maxime Ripard
  0 siblings, 0 replies; 23+ messages in thread
From: Maxime Ripard @ 2016-11-21 21:45 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Mike Turquette, Stephen Boyd, linux-arm-kernel, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 1670 bytes --]

On Sun, Nov 13, 2016 at 05:34:44PM +0800, Chen-Yu Tsai wrote:
> > +static struct ccu_nkmp pll_ve_clk = {
> > +       .enable         = BIT(31),
> > +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> > +       .k              = _SUNXI_CCU_MULT(4, 2),
> > +       .m              = _SUNXI_CCU_DIV(0, 2),
> > +       .p              = _SUNXI_CCU_DIV(16, 2),
> 
> Any chance we'll support the bypass switch on this one?

I'm not sure this will be useful to have it running at 24MHz.

> > +static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
> 
> Maybe we should set CLK_IS_CRITICAL on this one as well... in case the
> bootloader uses pll-periph for mbus, and none of the dram gates are enabled.

Ack.

> > +static SUNXI_CCU_GATE(hosc_clk,        "hosc", "osc24M", 0x050, BIT(0), 0);
> 
> Why the extra "hosc" clock here? You should probably just internalize "osc24M".

I'd prefer to model it as it is modelled in hardware: you have two
crystals, and then a gate within the CCU.

> > +static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
> > +                                           "pll-video0-2x", "pll-video1-2x" };
> > +static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
> > +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
> > +                                      csi_parents, csi_table,
> > +                                      0x134, 0, 5, 24, 2, BIT(31), 0);
> 
> Do you know if CSI needs to change the module clock?

Apparently not.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH 9/10] ARM: sun5i: Convert to CCU
  2016-11-13 15:01   ` Chen-Yu Tsai
@ 2016-11-21 22:04     ` Maxime Ripard
  0 siblings, 0 replies; 23+ messages in thread
From: Maxime Ripard @ 2016-11-21 22:04 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Mike Turquette, Stephen Boyd, linux-arm-kernel, linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 969 bytes --]

On Sun, Nov 13, 2016 at 11:01:27PM +0800, Chen-Yu Tsai wrote:
> >                         compatible = "allwinner,sun5i-a13-tcon";
> >                         reg = <0x01c0c000 0x1000>;
> >                         interrupts = <44>;
> > -                       resets = <&tcon_ch0_clk 1>;
> > +                       resets = <&ccu RST_LCD>;
> >                         reset-names = "lcd";
> > -                       clocks = <&ahb_gates 36>,
> > -                                <&tcon_ch0_clk>,
> > -                                <&tcon_ch1_clk>;
> > +                       clocks = <&ccu CLK_AHB_LCD>,
> > +                                <&ccu CLK_TCON_CH0>,
> > +                                <&ccu CLK_TCON_CH1>;
> 
> Just curious, is CLK_TCON_CH1_SCLK ever used?

Yes, this is an intermediate clock for the channel 1 clock.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

end of thread, other threads:[~2016-11-21 22:04 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-08 17:23 [PATCH 0/10] ARM: sun5i: Convert sun5i SoCs to sunxi-ng Maxime Ripard
2016-11-08 17:23 ` [PATCH 1/10] clk: sunxi-ng: multiplier: Add fractionnal support Maxime Ripard
2016-11-10  6:18   ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 2/10] clk: sunxi-ng: nkm: Deal with fixed post dividers Maxime Ripard
2016-11-13  3:48   ` Chen-Yu Tsai
2016-11-13  3:49     ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 3/10] clk: sunxi-ng: Implement multiplier offsets Maxime Ripard
2016-11-13  4:18   ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 4/10] clk: sunxi-ng: Add clocks and resets indices for sun5i Maxime Ripard
2016-11-13  4:29   ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 5/10] clk: sunxi-ng: Implement multiplier maximum Maxime Ripard
2016-11-13  4:30   ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 6/10] clk: sunxi-ng: Add A10s CCU driver Maxime Ripard
2016-11-13  9:34   ` Chen-Yu Tsai
2016-11-21 21:45     ` Maxime Ripard
2016-11-08 17:23 ` [PATCH 7/10] clk: sunxi-ng: Add A13 " Maxime Ripard
2016-11-13  9:55   ` Chen-Yu Tsai
2016-11-08 17:23 ` [PATCH 8/10] clk: sunxi-ng: Add GR8 driver Maxime Ripard
2016-11-08 17:23 ` [PATCH 9/10] ARM: sun5i: Convert to CCU Maxime Ripard
2016-11-13 15:01   ` Chen-Yu Tsai
2016-11-21 22:04     ` Maxime Ripard
2016-11-08 17:23 ` [PATCH 10/10] ARM: gr8: " Maxime Ripard
2016-11-12 23:51   ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).