* [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).