linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/3] clk: sunxi-ng: Add N-D-M-P-factor clock support
  2016-06-11 17:39 [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks Jean-Francois Moine
@ 2016-06-11 16:23 ` Jean-Francois Moine
  2016-06-11 16:50 ` [PATCH v2 2/3] clk: sunxi-ng: Add the A83T clocks and resets Jean-Francois Moine
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2016-06-11 16:23 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce support for the PLL clocks of the A83T and A80 SoCs
which are set from N, D1, D2, M and P factors.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 drivers/clk/sunxi-ng/Makefile     |   1 +
 drivers/clk/sunxi-ng/ccu_common.h |   1 +
 drivers/clk/sunxi-ng/ccu_ndmp.c   | 239 ++++++++++++++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu_ndmp.h   |  96 +++++++++++++++
 4 files changed, 337 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu_ndmp.c
 create mode 100644 drivers/clk/sunxi-ng/ccu_ndmp.h

diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index cafabf0..f0608cb 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -8,6 +8,7 @@ obj-y += ccu_fixed_factor.o
 obj-y += ccu_gate.o
 obj-y += ccu_mp.o
 obj-y += ccu_mux.o
+obj-y += ccu_ndmp.o
 obj-y += ccu_nk.o
 obj-y += ccu_nkm.o
 obj-y += ccu_nkmp.o
diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h
index fda2450..df3ae5e 100644
--- a/drivers/clk/sunxi-ng/ccu_common.h
+++ b/drivers/clk/sunxi-ng/ccu_common.h
@@ -23,6 +23,7 @@
 #define CCU_FEATURE_VARIABLE_PREDIV	BIT(3)
 #define CCU_FEATURE_FIXED_PREDIV	BIT(4)
 #define CCU_FEATURE_FIXED_POSTDIV	BIT(5)
+#define CCU_FEATURE_N1			BIT(6)
 
 struct device_node;
 
diff --git a/drivers/clk/sunxi-ng/ccu_ndmp.c b/drivers/clk/sunxi-ng/ccu_ndmp.c
new file mode 100644
index 0000000..5481527
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_ndmp.c
@@ -0,0 +1,239 @@
+/*
+ * PLL clocks of sun8iw6 (A83T) and sun9iw1 (A80)
+ *
+ * Copyright (c) 2016 Jean-Francois Moine <moinejf@free.fr>
+ *
+ * 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.
+ *
+ * The clock rates are computed as:
+ *	rate = parent_rate / d1 * n / d2 / m >> p
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/rational.h>
+#include <linux/iopoll.h>
+
+#include "ccu_gate.h"
+#include "ccu_ndmp.h"
+
+struct values {
+	int n, d1, d2, m, p;
+};
+
+static void ccu_ndmp_disable(struct clk_hw *hw)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+
+	return ccu_gate_helper_disable(&ndmp->common, ndmp->enable);
+}
+
+static int ccu_ndmp_enable(struct clk_hw *hw)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+
+	return ccu_gate_helper_enable(&ndmp->common, ndmp->enable);
+}
+
+static int ccu_ndmp_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+
+	return ccu_gate_helper_is_enabled(&ndmp->common, ndmp->enable);
+}
+
+static unsigned long ccu_ndmp_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+	int n, d1, d2, m, p;
+	unsigned long rate;
+	u32 reg;
+
+	reg = readl(ndmp->common.base + ndmp->common.reg);
+
+	rate = parent_rate;
+
+	if (ndmp->d1.width) {
+		d1 = reg >> ndmp->d1.shift;
+		d1 &= (1 << ndmp->d1.width) - 1;
+		rate /= (d1 + 1);
+	}
+
+	n = reg >> ndmp->n.shift;
+	n &= (1 << ndmp->n.width) - 1;
+	if (ndmp->common.features & CCU_FEATURE_N1)
+		n++;
+	rate *= n;
+
+	if (ndmp->d2.width) {
+		d2 = reg >> ndmp->d2.shift;
+		d2 &= (1 << ndmp->d2.width) - 1;
+		rate /= (d2 + 1);
+	}
+
+	if (ndmp->m.width) {
+		m = reg >> ndmp->m.shift;
+		m &= (1 << ndmp->m.width) - 1;
+		rate /= (m + 1);
+	}
+
+	if (ndmp->p.width) {
+		p = reg >> ndmp->p.shift;
+		p &= (1 << ndmp->p.width) - 1;
+		rate >>= p;
+	}
+
+	return rate;
+}
+
+/* all returned values are set here */
+/* d1 and d2 may be only 1 or 2 */
+static int ccu_ndmp_get_fact(struct ccu_ndmp *ndmp,
+			unsigned long rate, unsigned long prate,
+			struct values *p_v)
+{
+	int n;
+	int d1 = 0 + 1, d2 = 0 + 1, m = 1, p = 0, d;
+	unsigned long t;
+
+	/* m implies only n, d1, d2 and m (pll-audio) */
+	/*
+	 * Setting d1=1 and d2=2 keeps n and m small enough
+	 *	with error < 5/10000
+	 */
+	if (ndmp->m.width) {
+		unsigned long lun, lum;
+
+		d2 = 1 + 1;
+		t = prate / 2;
+		rational_best_approximation(rate, t,
+					1 << ndmp->n.width,
+					1 << ndmp->m.width,
+					&lun, &lum);
+		if (lum == 0)
+			return -EINVAL;
+		n = lun;
+		m = lum;
+
+	/* no d1 implies only n and p (pll-cxcpux) */
+	} else if (!ndmp->d1.width) {
+		n = rate / prate;
+		p = 0;		/* p is used only for rates under 288 MHz */
+
+	/* p implies only n, d1 and p (pll-videox) */
+	} else if (ndmp->p.width) {
+		d = 2 + ndmp->p.width;
+		n = rate / (prate / (1 << d));
+		if (n < 12) {
+			n *= 2;
+			d++;
+		}
+		while (n >= 12 * 2 && !(n & 1)) {
+			n /= 2;
+			if (--d == 0)
+				break;
+		}
+		if (d <= 1) {
+			d1 = d + 1;
+		} else {
+			d1 = 1 + 1;
+			p = d - 1;
+		}
+
+	/* only n, d1 and d2 (other plls) */
+	} else {
+		t = prate / 4;
+		n = rate / t;
+		if (n < 12) {
+			n *= 4;
+		} else if (n >= 12 * 2 && !(n & 1)) {
+			if (n >= 12 * 4 && !(n & 3)) {
+				n /= 4;
+			} else {
+				n /= 2;
+				d2 = 1 + 1;
+			}
+		} else {
+			d1 = d2 = 1 + 1;
+		}
+		if (n > (1 << ndmp->n.width))
+			return -EINVAL;
+	}
+
+	if (n < 12 || n > (1 << ndmp->n.width))
+		return -EINVAL;
+
+	p_v->n = n;
+	p_v->d1 = d1;
+	p_v->d2 = d2;
+	p_v->m = m;
+	p_v->p = p;
+
+	return 0;
+}
+
+static long ccu_ndmp_round_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *parent_rate)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+	struct values v;
+	int ret;
+
+	ret = ccu_ndmp_get_fact(ndmp, rate, *parent_rate, &v);
+	if (ret)
+		return 0;
+
+	return *parent_rate / v.d1 * v.n / v.d2 / v.m >> v.p;
+}
+
+static int ccu_ndmp_set_rate(struct clk_hw *hw, unsigned long rate,
+			   unsigned long parent_rate)
+{
+	struct ccu_ndmp *ndmp = hw_to_ccu_ndmp(hw);
+	unsigned long flags;
+	struct values v;
+	int ret;
+	u32 reg;
+
+	ret = ccu_ndmp_get_fact(ndmp, rate, parent_rate, &v);
+	if (ret)
+		return ret;
+	if (ndmp->common.features & CCU_FEATURE_N1)
+		v.n--;
+
+	spin_lock_irqsave(ndmp->common.lock, flags);
+
+	reg = readl(ndmp->common.base + ndmp->common.reg) &
+		~((((1 << ndmp->n.width) - 1) << ndmp->n.shift) |
+		  (((1 << ndmp->d1.width) - 1) << ndmp->d1.shift) |
+		  (((1 << ndmp->d2.width) - 1) << ndmp->d2.shift) |
+		  (((1 << ndmp->m.width) - 1) << ndmp->m.shift) |
+		  (((1 << ndmp->p.width) - 1) << ndmp->p.shift));
+
+	writel(reg | (v.n << ndmp->n.shift) |
+			((v.d1 - 1) << ndmp->d1.shift) |
+			((v.d2 - 1) << ndmp->d2.shift) |
+			((v.m - 1) << ndmp->m.shift) |
+			(v.p << ndmp->p.shift),
+	       ndmp->common.base + ndmp->common.reg);
+
+	spin_unlock_irqrestore(ndmp->common.lock, flags);
+
+	WARN_ON(readl_relaxed_poll_timeout(ndmp->common.base + ndmp->reg_lock,
+					   reg, !(reg & ndmp->lock), 50, 5000));
+
+	return 0;
+}
+
+const struct clk_ops ccu_ndmp_ops = {
+	.disable	= ccu_ndmp_disable,
+	.enable		= ccu_ndmp_enable,
+	.is_enabled	= ccu_ndmp_is_enabled,
+
+	.recalc_rate	= ccu_ndmp_recalc_rate,
+	.round_rate	= ccu_ndmp_round_rate,
+	.set_rate	= ccu_ndmp_set_rate,
+};
diff --git a/drivers/clk/sunxi-ng/ccu_ndmp.h b/drivers/clk/sunxi-ng/ccu_ndmp.h
new file mode 100644
index 0000000..5341861
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_ndmp.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Jean-Francois Moine <moinejf@free.fr>
+ *
+ * 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.
+ */
+
+#ifndef _CCU_NDMP_H_
+#define _CCU_NDMP_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+#include "ccu_mult.h"
+
+struct ccu_ndmp {
+	u32			enable;
+	u32			lock;
+	u16			reg_lock;
+
+	struct _ccu_mult	n;
+	struct _ccu_mult	d1;
+	struct _ccu_mult	d2;
+	struct _ccu_mult	m;
+	struct _ccu_mult	p;
+
+	struct ccu_common	common;
+};
+
+#define SUNXI_CCU_NDMP(_struct, _name, _parent, _reg,			\
+			_nshift, _nwidth,				\
+			_d1shift, _d1width,				\
+			_d2shift, _d2width,				\
+			_mshift, _mwidth,				\
+			_pshift, _pwidth,				\
+			_gate, _lock, _reglock, _flags)			\
+	struct ccu_ndmp _struct = {					\
+		.enable		= _gate,				\
+		.lock		= _lock,				\
+		.reg_lock	= _reglock,				\
+		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
+		.d1		= _SUNXI_CCU_MULT(_d1shift, _d1width),	\
+		.d2		= _SUNXI_CCU_MULT(_d2shift, _d2width),	\
+		.m		= _SUNXI_CCU_MULT(_mshift, _mwidth),	\
+		.p		= _SUNXI_CCU_MULT(_pshift, _pwidth),	\
+		.common		= {					\
+			.reg		= _reg,				\
+			.hw.init	= SUNXI_HW_INIT(_name,		\
+							_parent,	\
+							&ccu_ndmp_ops,	\
+							_flags),	\
+		},							\
+	}
+
+#define SUNXI_CCU_NDMP_N1(_struct, _name, _parent, _reg,		\
+			_nshift, _nwidth,				\
+			_d1shift, _d1width,				\
+			_d2shift, _d2width,				\
+			_mshift, _mwidth,				\
+			_pshift, _pwidth,				\
+			_gate, _lock, _reglock, _flags)			\
+	struct ccu_ndmp _struct = {					\
+		.enable		= _gate,				\
+		.lock		= _lock,				\
+		.reg_lock	= _reglock,				\
+		.n		= _SUNXI_CCU_MULT(_nshift, _nwidth),	\
+		.d1		= _SUNXI_CCU_MULT(_d1shift, _d1width),	\
+		.d2		= _SUNXI_CCU_MULT(_d2shift, _d2width),	\
+		.m		= _SUNXI_CCU_MULT(_mshift, _mwidth),	\
+		.p		= _SUNXI_CCU_MULT(_pshift, _pwidth),	\
+		.common		= {					\
+			.reg		= _reg,				\
+			.features	= CCU_FEATURE_N1,		\
+			.hw.init	= SUNXI_HW_INIT(_name,		\
+							_parent,	\
+							&ccu_ndmp_ops,	\
+							_flags),	\
+		},							\
+	}
+
+static inline struct ccu_ndmp *hw_to_ccu_ndmp(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_ndmp, common);
+}
+
+extern const struct clk_ops ccu_ndmp_ops;
+
+#endif /* _CCU_NDMP_H_ */
-- 
2.8.4

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

* [PATCH v2 2/3] clk: sunxi-ng: Add the A83T clocks and resets
  2016-06-11 17:39 [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks Jean-Francois Moine
  2016-06-11 16:23 ` [PATCH v2 1/3] clk: sunxi-ng: Add N-D-M-P-factor clock support Jean-Francois Moine
@ 2016-06-11 16:50 ` Jean-Francois Moine
  2016-06-11 17:04 ` [PATCH v2 3/3] dt: sun8i: Define the clocks of the A83T Jean-Francois Moine
       [not found] ` <CAEzqOZuGbn0Qc62mLpPKuH+n8doVLQec5Lg-cvT2C5tqh1GFzg@mail.gmail.com>
  3 siblings, 0 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2016-06-11 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add the clocks and resets found in the A83T CCU.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 drivers/clk/sunxi-ng/Makefile          |   2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c  | 675 +++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/sun8i-a83t.h | 150 ++++++++
 include/dt-bindings/reset/sun8i-a83t.h |  94 +++++
 4 files changed, 920 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
 create mode 100644 include/dt-bindings/clock/sun8i-a83t.h
 create mode 100644 include/dt-bindings/reset/sun8i-a83t.h

diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index f0608cb..6511c4c 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -15,4 +15,4 @@ obj-y += ccu_nkmp.o
 obj-y += ccu_nm.o
 obj-y += ccu_phase.o
 
-obj-$(CONFIG_MACH_SUN8I) += ccu-sun8i-h3.o
+obj-$(CONFIG_MACH_SUN8I) += ccu-sun8i-h3.o ccu-sun8i-a83t.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
new file mode 100644
index 0000000..eec9ca4
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2016 Jean-Francois Moine <moinejf@free.fr>
+ * Based on the H3 version from
+ * 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 <dt-bindings/clock/sun8i-a83t.h>
+#include <dt-bindings/reset/sun8i-a83t.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_fixed_factor.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_ndmp.h"
+#include "ccu_phase.h"
+
+/* 2 * cpux */
+/*	rate = 24MHz * n */
+static SUNXI_CCU_NDMP(pll_c0cpux_clk, "pll-c0cpux", "osc24M", 0x000,
+			8, 8,		/* N */
+			0, 0,		/* D1 */
+			0, 0,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(0), 0x20c,	/* lock */
+			0);
+
+static SUNXI_CCU_NDMP(pll_c1cpux_clk, "pll-c1cpux", "osc24M", 0x004,
+			8, 8,		/* N */
+			0, 0,		/* D1 */
+			0, 0,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(1), 0x20c,	/* lock */
+			0);
+
+/* audio */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) / (p + 1) */
+static SUNXI_CCU_NDMP(pll_audio_clk, "pll-audio", "osc24M", 0x008,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 6,		/* M (p post-div) */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(2), 0x20c,	/* lock */
+			0);
+
+/* video 0 */
+/*	rate = 24MHz * n / (d1 + 1) >> p */
+static SUNXI_CCU_NDMP(pll_video0_clk, "pll-video0", "osc24M", 0x010,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			0, 0,		/* D2 */
+			0, 0,		/* M */
+			0, 2,		/* P */
+			BIT(31),	/* gate */
+			BIT(3), 0x20c,	/* lock */
+			0);
+
+/* video engine */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) */
+static SUNXI_CCU_NDMP(pll_ve_clk, "pll-ve", "osc24M", 0x018,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(4), 0x20c,	/* lock */
+			0);
+
+/* ddr */
+/*	rate = 24MHz * (n + 1) / (d1 + 1) / (d2 + 1)
+ *	bit 21: DDR_CLOCK = PLL_DDR / PLL_PERIPH (default DDR)
+ *	bit 22: to be set after rate is changed
+ */
+static SUNXI_CCU_NDMP_N1(pll_ddr_clk, "pll-ddr", "osc24M", 0x020,
+			8, 6,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(5), 0x20c,	/* lock */
+			CLK_IGNORE_UNUSED);
+
+/* periph */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) */
+static SUNXI_CCU_NDMP(pll_periph_clk, "pll-periph", "osc24M", 0x028,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(6), 0x20c,	/* lock */
+			0);
+
+/* gpu */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) */
+static SUNXI_CCU_NDMP(pll_gpu_clk, "pll-gpu", "osc24M", 0x038,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(7), 0x20c,	/* lock */
+			0);
+
+/* hsic */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) */
+static SUNXI_CCU_NDMP(pll_hsic_clk, "pll-hsic", "osc24M", 0x044,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(8), 0x20c,	/* lock */
+			CLK_IGNORE_UNUSED);
+
+/* display engine */
+/*	rate = 24MHz * n / (d1 + 1) / (d2 + 1) */
+static SUNXI_CCU_NDMP(pll_de_clk, "pll-de", "osc24M", 0x048,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			18, 1,		/* D2 */
+			0, 0,		/* M */
+			0, 0,		/* P */
+			BIT(31),	/* gate */
+			BIT(9), 0x20c,	/* lock */
+			0);
+/* video 1 */
+/*	rate = 24MHz * n / (d1 + 1) >> p */
+static SUNXI_CCU_NDMP(pll_video1_clk, "pll-video1", "osc24M", 0x04c,
+			8, 8,		/* N */
+			16, 1,		/* D1 */
+			0, 0,		/* D2 */
+			0, 0,		/* M */
+			0, 2,		/* P */
+			BIT(31),	/* gate */
+			BIT(10), 0x20c,	/* lock */
+			0);
+
+static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
+static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
+		     0x050, 12, 1, CLK_IS_CRITICAL);
+
+static SUNXI_CCU_M(axi0_clk, "axi0", "c0cpux",
+		   0x050, 0, 2, CLK_IGNORE_UNUSED);
+
+static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
+static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
+		     0x050, 28, 1, CLK_IS_CRITICAL);
+
+static SUNXI_CCU_M(axi1_clk, "axi1", "c1cpux",
+		   0x050, 16, 2, CLK_IGNORE_UNUSED);
+
+static const char * const ahb1_parents[] = { "osc32k", "osc24M",
+						"pll-periph" };
+static struct ccu_div ahb1_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.mux		= {
+		.shift	= 12,
+		.width	= 2,
+
+		.variable_prediv	= {
+			.index	= 2,
+			.shift	= 6,
+			.width	= 2,
+		},
+	},
+
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_VARIABLE_PREDIV,
+		.hw.init	= SUNXI_HW_INIT_PARENTS("ahb1",
+							ahb1_parents,
+							&ccu_div_ops,
+							0),
+	},
+};
+
+static SUNXI_CCU_M(apb1_clk, "apb1", "ahb1", 0x054, 8, 2, 0);
+
+static const char * const apb2_parents[] = { "osc32k", "osc24M",
+						"pll-periph", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static const char * const ahb2_parents[] = { "ahb1", "pll-periph" };
+static struct ccu_mux ahb2_clk = {
+	.mux		= {
+		.shift	= 0,
+		.width	= 2,
+
+		.fixed_prediv	= {
+			.index	= 1,
+			.div	= 2,
+		},
+	},
+
+	.common		= {
+		.reg		= 0x05c,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= SUNXI_HW_INIT_PARENTS("ahb2",
+							ahb2_parents,
+							&ccu_mux_ops,
+							0),
+	},
+};
+
+static SUNXI_CCU_GATE(bus_mipi_dsi_clk,	"bus-mipi-dsi",	"ahb1",
+		      0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ss_clk,	"bus-ss",	"ahb1",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_dma_clk,	"bus-dma",	"ahb1",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(bus_mmc0_clk,	"bus-mmc0",	"ahb1",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk,	"bus-mmc1",	"ahb1",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(bus_mmc2_clk,	"bus-mmc2",	"ahb1",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(bus_nand_clk,	"bus-nand",	"ahb1",
+		      0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(bus_dram_clk,	"bus-dram",	"ahb1",
+		      0x060, BIT(14), CLK_IGNORE_UNUSED);
+static SUNXI_CCU_GATE(bus_emac_clk,	"bus-emac",	"ahb2",
+		      0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_hstimer_clk,	"bus-hstimer",	"ahb1",
+		      0x060, BIT(19), 0);
+static SUNXI_CCU_GATE(bus_spi0_clk,	"bus-spi0",	"ahb1",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk,	"bus-spi1",	"ahb1",
+		      0x060, BIT(21), 0);
+static SUNXI_CCU_GATE(bus_usbdrd_clk,	"bus-usbdrd",	"ahb2",
+		      0x060, BIT(24), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk,	"bus-ehci0",	"ahb2",
+		      0x060, BIT(26), 0);
+static SUNXI_CCU_GATE(bus_ehci1_clk,	"bus-ehci1",	"ahb2",
+		      0x060, BIT(27), 0);
+static SUNXI_CCU_GATE(bus_ohci0_clk,	"bus-ohci0",	"ahb2",
+		      0x060, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ve_clk,	"bus-ve",	"ahb1",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_tcon0_clk,	"bus-tcon0",	"ahb1",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_tcon1_clk,	"bus-tcon1",	"ahb1",
+		      0x064, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_csi_clk,	"bus-csi",	"ahb1",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_hdmi_clk,	"bus-hdmi",	"ahb1",
+		      0x064, BIT(11), 0);
+static SUNXI_CCU_GATE(bus_de_clk,	"bus-de",	"ahb1",
+		      0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
+		      0x064, BIT(20), 0);
+static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
+		      0x064, BIT(21), 0);
+static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
+		      0x064, BIT(22), 0);
+
+static SUNXI_CCU_GATE(bus_spdif_clk,	"bus-spdif",	"apb1",
+		      0x068, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_pio_clk,	"bus-pio",	"apb1",
+		      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_daudio0_clk,	"bus-daudio0",	"apb1",
+		      0x068, BIT(12), 0);
+static SUNXI_CCU_GATE(bus_daudio1_clk,	"bus-daudio1",	"apb1",
+		      0x068, BIT(13), 0);
+static SUNXI_CCU_GATE(bus_daudio2_clk,	"bus-daudio2",	"apb1",
+		      0x068, BIT(14), 0);
+static SUNXI_CCU_GATE(bus_tdm_clk,	"bus-tdm",	"apb1",
+		      0x068, BIT(15), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk,	"bus-i2c0",	"apb2",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk,	"bus-i2c1",	"apb2",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_i2c2_clk,	"bus-i2c2",	"apb2",
+		      0x06c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_uart0_clk,	"bus-uart0",	"apb2",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk,	"bus-uart1",	"apb2",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk,	"bus-uart2",	"apb2",
+		      0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk,	"bus-uart3",	"apb2",
+		      0x06c, BIT(19), 0);
+static SUNXI_CCU_GATE(bus_uart4_clk,	"bus-uart4",	"apb2",
+		      0x06c, BIT(20), 0);
+
+static const char * const cci400_parents[] = { "osc24M", "pll-periph",
+						"pll-hsic" };
+static SUNXI_CCU_M_WITH_MUX(cci400_clk, "cci400", cci400_parents,
+			    0x078, 0, 2, 24, 2, 0);
+
+static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
+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_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
+		       0x088, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
+		       0x088, 8, 3, 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_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
+		       0x08c, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
+		       0x08c, 8, 3, 0);
+
+/* mode select */
+static SUNXI_CCU_M_WITH_MUX(mmc2mod_clk, "mmc2mod", mod0_default_parents,
+			    0x090, 30, 1, 24, 2, 0);
+
+static struct ccu_mp mmc2_clk = {
+	.enable		= BIT(31),
+
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.m		= _SUNXI_CCU_DIV(0, 4),
+
+	.common		= {
+		.reg		= 0x090,
+		.hw.init	= SUNXI_HW_INIT("mmc2",
+						"mmc2mod",
+						&ccu_mp_ops,
+						CLK_SET_RATE_PARENT),
+	},
+};
+
+static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
+		       0x090, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
+		       0x090, 8, 3, 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_M(daudio0_clk, "daudio0", "pll-audio", 0x0b0, 0, 4, 0);
+
+static SUNXI_CCU_M(daudio1_clk, "daudio1", "pll-audio", 0x0b4, 0, 4, 0);
+
+static SUNXI_CCU_M(daudio2_clk, "daudio2", "pll-audio", 0x0b8, 0, 4, 0);
+
+static SUNXI_CCU_M(tdm_clk, "tdm", "pll-audio", 0x0bc, 0, 4, 0);
+
+static SUNXI_CCU_M(spdif_clk, "spdif", "pll-audio", 0x0c0, 0, 4, 0);
+
+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0x0cc, BIT(9), 0);
+static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", 0x0cc, BIT(10), 0);
+
+static SUNXI_CCU_GATE(osc12mx2_clk, "osc12Mx2", "osc24M", 0x0cc, BIT(11), 0);
+static SUNXI_CCU_FIXED_FACTOR(osc12m_clk, "osc12M", "osc12Mx2",
+				2, 1, CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(ohci0_clk, "ohci0", "osc24M", 0x0cc, BIT(16), 0);
+
+static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 0x0f4, 0, 4,
+							CLK_IGNORE_UNUSED);
+/* bit 16 SDRCLK_UPD (configuration update) */
+
+/* pll_ddr config not done */
+
+static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", 0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram", 0x100, BIT(1), 0);
+
+static SUNXI_CCU_GATE(tcon0_clk, "tcon0", "pll-video0", 0x118, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(tcon1_clk, "tcon1", "pll-video1",
+						0x11c, 0, 4, BIT(31), 0);
+
+static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
+
+static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
+
+/* hack: "osc32k" is used for no parent */
+static const char * const csi_sclk_parents[] = { "pll-periph",
+				"osc32k", "osc32k", "osc32k", "osc32k",
+				"pll-ve" };
+static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents,
+				 0x134, 16, 4, 24, 3, BIT(31), 0);
+
+/* hack: "osc32k" is used for no parent */
+static const char * const csi_mclk_parents[] = {"osc32k", "osc32k", "osc32k",
+				"pll-periph", "osc32k",
+				"osc24M"};
+static SUNXI_CCU_M_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents,
+				 0x134, 0, 5, 8, 3, BIT(15), 0);
+
+static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 3, BIT(31), 0);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(hdmi_clk, "hdmi", "pll-video1",
+			     0x150, 0, 4, BIT(31), 0);
+
+static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x154, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "osc24M", "pll-periph",
+						"pll-ddr" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_M_WITH_GATE(mipi_dsi0_clk, "mipi-dsi0", "pll-video0",
+			     0x168, 0, 4, BIT(31), 0);
+
+static const char * const mipi_dsi1_parents[] = { "osc24M",
+/* hack: "osc32k" is used for no parent */
+				"osc32k", "osc32k", "osc32k", "osc32k",
+					"osc32k", "osc32k", "osc32k", "osc32k",
+				"pll-video0" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi1_clk, "mipi-dsi1", mipi_dsi1_parents,
+				 0x16c, 0, 4, 24, 4, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu",
+			     0x1a0, 0, 3, BIT(31), 0);
+
+static const char * const gpu_mem_parents[] = { "pll-gpu", "pll-periph" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_mem_clk, "gpu-mem", gpu_mem_parents,
+				 0x1a4, 0, 3, 24, 1, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(gpu_hyd_clk, "gpu-hyd", "pll-gpu",
+			     0x1a8, 0, 3, BIT(31), 0);
+
+static struct ccu_common *sun8i_a83t_ccu_clks[] = {
+	[CLK_PLL_C0CPUX]	= &pll_c0cpux_clk.common,
+	[CLK_PLL_C1CPUX]	= &pll_c1cpux_clk.common,
+	[CLK_PLL_AUDIO]		= &pll_audio_clk.common,
+	[CLK_PLL_VIDEO0]	= &pll_video0_clk.common,
+	[CLK_PLL_VE]		= &pll_ve_clk.common,
+	[CLK_PLL_DDR]		= &pll_ddr_clk.common,
+	[CLK_PLL_PERIPH]	= &pll_periph_clk.common,
+	[CLK_PLL_GPU]		= &pll_gpu_clk.common,
+	[CLK_PLL_HSIC]		= &pll_hsic_clk.common,
+	[CLK_PLL_DE]		= &pll_de_clk.common,
+	[CLK_PLL_VIDEO1]	= &pll_video1_clk.common,
+	[CLK_C0CPUX]		= &c0cpux_clk.common,
+	[CLK_AXI0]		= &axi0_clk.common,
+	[CLK_C1CPUX]		= &c1cpux_clk.common,
+	[CLK_AXI1]		= &axi1_clk.common,
+	[CLK_AHB1]		= &ahb1_clk.common,
+	[CLK_APB1]		= &apb1_clk.common,
+	[CLK_APB2]		= &apb2_clk.common,
+	[CLK_AHB2]		= &ahb2_clk.common,
+	[CLK_BUS_MIPI_DSI]	= &bus_mipi_dsi_clk.common,
+	[CLK_BUS_SS]		= &bus_ss_clk.common,
+	[CLK_BUS_DMA]		= &bus_dma_clk.common,
+	[CLK_BUS_MMC0]		= &bus_mmc0_clk.common,
+	[CLK_BUS_MMC1]		= &bus_mmc1_clk.common,
+	[CLK_BUS_MMC2]		= &bus_mmc2_clk.common,
+	[CLK_BUS_NAND]		= &bus_nand_clk.common,
+	[CLK_BUS_DRAM]		= &bus_dram_clk.common,
+	[CLK_BUS_EMAC]		= &bus_emac_clk.common,
+	[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common,
+	[CLK_BUS_SPI0]		= &bus_spi0_clk.common,
+	[CLK_BUS_SPI1]		= &bus_spi1_clk.common,
+	[CLK_BUS_USBDRD]	= &bus_usbdrd_clk.common,
+	[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common,
+	[CLK_BUS_EHCI1]		= &bus_ehci1_clk.common,
+	[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common,
+	[CLK_BUS_VE]		= &bus_ve_clk.common,
+	[CLK_BUS_TCON0]		= &bus_tcon0_clk.common,
+	[CLK_BUS_TCON1]		= &bus_tcon1_clk.common,
+	[CLK_BUS_CSI]		= &bus_csi_clk.common,
+	[CLK_BUS_HDMI]		= &bus_hdmi_clk.common,
+	[CLK_BUS_DE]		= &bus_de_clk.common,
+	[CLK_BUS_GPU]		= &bus_gpu_clk.common,
+	[CLK_BUS_MSGBOX]	= &bus_msgbox_clk.common,
+	[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common,
+	[CLK_BUS_SPDIF]		= &bus_spdif_clk.common,
+	[CLK_BUS_PIO]		= &bus_pio_clk.common,
+	[CLK_BUS_DAUDIO0]	= &bus_daudio0_clk.common,
+	[CLK_BUS_DAUDIO1]	= &bus_daudio1_clk.common,
+	[CLK_BUS_DAUDIO2]	= &bus_daudio2_clk.common,
+	[CLK_BUS_TDM]		= &bus_tdm_clk.common,
+	[CLK_BUS_I2C0]		= &bus_i2c0_clk.common,
+	[CLK_BUS_I2C1]		= &bus_i2c1_clk.common,
+	[CLK_BUS_I2C2]		= &bus_i2c2_clk.common,
+	[CLK_BUS_UART0]		= &bus_uart0_clk.common,
+	[CLK_BUS_UART1]		= &bus_uart1_clk.common,
+	[CLK_BUS_UART2]		= &bus_uart2_clk.common,
+	[CLK_BUS_UART3]		= &bus_uart3_clk.common,
+	[CLK_BUS_UART4]		= &bus_uart4_clk.common,
+	[CLK_CCI400]		= &cci400_clk.common,
+	[CLK_NAND]		= &nand_clk.common,
+	[CLK_MMC0]		= &mmc0_clk.common,
+	[CLK_MMC0_SAMPLE]	= &mmc0_sample_clk.common,
+	[CLK_MMC0_OUTPUT]	= &mmc0_output_clk.common,
+	[CLK_MMC1]		= &mmc1_clk.common,
+	[CLK_MMC1_SAMPLE]	= &mmc1_sample_clk.common,
+	[CLK_MMC1_OUTPUT]	= &mmc1_output_clk.common,
+	[CLK_MMC2MOD]		= &mmc2mod_clk.common,
+	[CLK_MMC2]		= &mmc2_clk.common,
+	[CLK_MMC2_SAMPLE]	= &mmc2_sample_clk.common,
+	[CLK_MMC2_OUTPUT]	= &mmc2_output_clk.common,
+	[CLK_SS]		= &ss_clk.common,
+	[CLK_SPI0]		= &spi0_clk.common,
+	[CLK_SPI1]		= &spi1_clk.common,
+	[CLK_DAUDIO0]		= &daudio0_clk.common,
+	[CLK_DAUDIO1]		= &daudio1_clk.common,
+	[CLK_DAUDIO2]		= &daudio2_clk.common,
+	[CLK_TDM]		= &tdm_clk.common,
+	[CLK_SPDIF]		= &spdif_clk.common,
+	[CLK_USB_PHY0]		= &usb_phy0_clk.common,
+	[CLK_USB_PHY1]		= &usb_phy1_clk.common,
+	[CLK_USB_HSIC]		= &usb_hsic_clk.common,
+	[CLK_OSC12M]		= &osc12m_clk.common,
+	[CLK_OHCI0]		= &ohci0_clk.common,
+	[CLK_DRAM]		= &dram_clk.common,
+	[CLK_DRAM_VE]		= &dram_ve_clk.common,
+	[CLK_DRAM_CSI]		= &dram_csi_clk.common,
+	[CLK_TCON0]		= &tcon0_clk.common,
+	[CLK_TCON1]		= &tcon1_clk.common,
+	[CLK_CSI_MISC]		= &csi_misc_clk.common,
+	[CLK_MIPI_CSI]		= &mipi_csi_clk.common,
+	[CLK_CSI_SCLK]		= &csi_sclk_clk.common,
+	[CLK_CSI_MCLK]		= &csi_mclk_clk.common,
+	[CLK_VE]		= &ve_clk.common,
+	[CLK_AVS]		= &avs_clk.common,
+	[CLK_HDMI]		= &hdmi_clk.common,
+	[CLK_HDMI_DDC]		= &hdmi_ddc_clk.common,
+	[CLK_MBUS]		= &mbus_clk.common,
+	[CLK_MIPI_DSI0]		= &mipi_dsi0_clk.common,
+	[CLK_MIPI_DSI1]		= &mipi_dsi1_clk.common,
+	[CLK_GPU_CORE]		= &gpu_core_clk.common,
+	[CLK_GPU_MEM]		= &gpu_mem_clk.common,
+	[CLK_GPU_HYD]		= &gpu_hyd_clk.common,
+	[CLK_OSC12MX2]		= &osc12mx2_clk.common,
+};
+
+static struct ccu_reset_map sun8i_a83t_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		=  { 0x0cc, BIT(1) },
+	[RST_USB_HSIC]		=  { 0x0cc, BIT(2) },
+
+	[RST_DRAM]		=  { 0x0f4, BIT(31) },
+	[RST_MBUS]		=  { 0x0fc, BIT(31) },
+
+	[RST_BUS_MIPI_DSI]	=  { 0x2c0, BIT(1) },
+	[RST_BUS_CE]		=  { 0x2c0, BIT(5) },
+	[RST_BUS_DMA]		=  { 0x2c0, BIT(6) },
+	[RST_BUS_MMC0]		=  { 0x2c0, BIT(8) },
+	[RST_BUS_MMC1]		=  { 0x2c0, BIT(9) },
+	[RST_BUS_MMC2]		=  { 0x2c0, BIT(10) },
+	[RST_BUS_NAND]		=  { 0x2c0, BIT(13) },
+	[RST_BUS_DRAM]		=  { 0x2c0, BIT(14) },
+	[RST_BUS_EMAC]		=  { 0x2c0, BIT(17) },
+	[RST_BUS_HSTIMER]	=  { 0x2c0, BIT(19) },
+	[RST_BUS_SPI0]		=  { 0x2c0, BIT(20) },
+	[RST_BUS_SPI1]		=  { 0x2c0, BIT(21) },
+	[RST_BUS_USBDRD]	=  { 0x2c0, BIT(24) },
+	[RST_BUS_EHCI0]		=  { 0x2c0, BIT(26) },
+	[RST_BUS_EHCI1]		=  { 0x2c0, BIT(27) },
+	[RST_BUS_OHCI0]		=  { 0x2c0, BIT(29) },
+
+	[RST_BUS_VE]		=  { 0x2c4, BIT(0) },
+	[RST_BUS_TCON0]		=  { 0x2c4, BIT(4) },
+	[RST_BUS_TCON1]		=  { 0x2c4, BIT(5) },
+	[RST_BUS_CSI]		=  { 0x2c4, BIT(8) },
+	[RST_BUS_HDMI0]		=  { 0x2c4, BIT(10) },
+	[RST_BUS_HDMI1]		=  { 0x2c4, BIT(11) },
+	[RST_BUS_DE]		=  { 0x2c4, BIT(12) },
+	[RST_BUS_GPU]		=  { 0x2c4, BIT(20) },
+	[RST_BUS_MSGBOX]	=  { 0x2c4, BIT(21) },
+	[RST_BUS_SPINLOCK]	=  { 0x2c4, BIT(22) },
+
+	[RST_BUS_LVDS]		=  { 0x2c8, BIT(0) },
+
+	[RST_BUS_SPDIF]		=  { 0x2d0, BIT(1) },
+	[RST_BUS_DAUDIO0]	=  { 0x2d0, BIT(12) },
+	[RST_BUS_DAUDIO1]	=  { 0x2d0, BIT(13) },
+	[RST_BUS_DAUDIO2]	=  { 0x2d0, BIT(14) },
+	[RST_BUS_TDM]		=  { 0x2d0, BIT(15) },
+
+	[RST_BUS_I2C0]		=  { 0x2d8, BIT(0) },
+	[RST_BUS_I2C1]		=  { 0x2d8, BIT(1) },
+	[RST_BUS_I2C2]		=  { 0x2d8, BIT(2) },
+	[RST_BUS_UART0]		=  { 0x2d8, BIT(16) },
+	[RST_BUS_UART1]		=  { 0x2d8, BIT(17) },
+	[RST_BUS_UART2]		=  { 0x2d8, BIT(18) },
+	[RST_BUS_UART3]		=  { 0x2d8, BIT(19) },
+	[RST_BUS_UART4]		=  { 0x2d8, BIT(20) },
+};
+
+static const struct sunxi_ccu_desc sun8i_a83t_ccu_desc = {
+	.clks		= sun8i_a83t_ccu_clks,
+	.num_clks	= ARRAY_SIZE(sun8i_a83t_ccu_clks),
+
+	.resets		= sun8i_a83t_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun8i_a83t_ccu_resets),
+};
+
+static void __init sun8i_a83t_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+
+	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;
+	}
+
+	sunxi_ccu_probe(node, reg, &sun8i_a83t_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_a83t_ccu, "allwinner,sun8i-a83t-ccu",
+	       sun8i_a83t_ccu_setup);
diff --git a/include/dt-bindings/clock/sun8i-a83t.h b/include/dt-bindings/clock/sun8i-a83t.h
new file mode 100644
index 0000000..4cf3b9f
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-a83t.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 Jean-Francois Moine <moinejf@free.fr>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN8I_A83T_H_
+#define _DT_BINDINGS_CLK_SUN8I_A83T_H_
+
+#define CLK_PLL_C0CPUX		0
+#define CLK_PLL_C1CPUX		1
+#define CLK_PLL_AUDIO		2
+#define CLK_PLL_VIDEO0		3
+#define CLK_PLL_VE		4
+#define CLK_PLL_DDR		5
+#define CLK_PLL_PERIPH		6
+#define CLK_PLL_GPU		7
+#define CLK_PLL_HSIC		8
+#define CLK_PLL_DE		9
+#define CLK_PLL_VIDEO1		10
+#define CLK_C0CPUX		11
+#define CLK_AXI0		12
+#define CLK_C1CPUX		13
+#define CLK_AXI1		14
+#define CLK_AHB1		15
+#define CLK_APB1		16
+#define CLK_APB2		17
+#define CLK_AHB2		18
+#define CLK_BUS_MIPI_DSI	19
+#define CLK_BUS_SS		20
+#define CLK_BUS_DMA		21
+#define CLK_BUS_MMC0		22
+#define CLK_BUS_MMC1		23
+#define CLK_BUS_MMC2		24
+#define CLK_BUS_NAND		25
+#define CLK_BUS_DRAM		26
+#define CLK_BUS_EMAC		27
+#define CLK_BUS_HSTIMER		28
+#define CLK_BUS_SPI0		29
+#define CLK_BUS_SPI1		30
+#define CLK_BUS_USBDRD		31
+#define CLK_BUS_EHCI0		32
+#define CLK_BUS_EHCI1		33
+#define CLK_BUS_OHCI0		34
+#define CLK_BUS_VE		35
+#define CLK_BUS_TCON0		36
+#define CLK_BUS_TCON1		37
+#define CLK_BUS_CSI		38
+#define CLK_BUS_HDMI		39
+#define CLK_BUS_DE		40
+#define CLK_BUS_GPU		41
+#define CLK_BUS_MSGBOX		42
+#define CLK_BUS_SPINLOCK	43
+#define CLK_BUS_SPDIF		44
+#define CLK_BUS_PIO		45
+#define CLK_BUS_DAUDIO0		46
+#define CLK_BUS_DAUDIO1		47
+#define CLK_BUS_DAUDIO2		48
+#define CLK_BUS_TDM		49
+#define CLK_BUS_I2C0		50
+#define CLK_BUS_I2C1		51
+#define CLK_BUS_I2C2		52
+#define CLK_BUS_UART0		53
+#define CLK_BUS_UART1		54
+#define CLK_BUS_UART2		55
+#define CLK_BUS_UART3		56
+#define CLK_BUS_UART4		57
+#define CLK_CCI400		58
+#define CLK_NAND		59
+#define CLK_MMC0		60
+#define CLK_MMC0_SAMPLE		61
+#define CLK_MMC0_OUTPUT		62
+#define CLK_MMC1		63
+#define CLK_MMC1_SAMPLE		64
+#define CLK_MMC1_OUTPUT		65
+#define CLK_MMC2MOD		66
+#define CLK_MMC2		67
+#define CLK_MMC2_SAMPLE		68
+#define CLK_MMC2_OUTPUT		69
+#define CLK_SS			70
+#define CLK_SPI0		71
+#define CLK_SPI1		72
+#define CLK_DAUDIO0		73
+#define CLK_DAUDIO1		74
+#define CLK_DAUDIO2		75
+#define CLK_TDM			76
+#define CLK_SPDIF		77
+#define CLK_USB_PHY0		78
+#define CLK_USB_PHY1		79
+#define CLK_USB_HSIC		80
+#define CLK_OSC12M		81
+#define CLK_OHCI0		82
+#define CLK_DRAM		83
+#define CLK_DRAM_VE		84
+#define CLK_DRAM_CSI		85
+#define CLK_TCON0		86
+#define CLK_TCON1		87
+#define CLK_CSI_MISC		88
+#define CLK_MIPI_CSI		89
+#define CLK_CSI_SCLK		90
+#define CLK_CSI_MCLK		91
+#define CLK_VE			92
+#define CLK_AVS			93
+#define CLK_HDMI		94
+#define CLK_HDMI_DDC		95
+#define CLK_MBUS		96
+#define CLK_MIPI_DSI0		97
+#define CLK_MIPI_DSI1		98
+#define CLK_GPU_CORE		99
+#define CLK_GPU_MEM		100
+#define CLK_GPU_HYD		101
+#define CLK_OSC12MX2		102
+
+#endif /* _DT_BINDINGS_CLK_SUN8I_A83T_H_ */
diff --git a/include/dt-bindings/reset/sun8i-a83t.h b/include/dt-bindings/reset/sun8i-a83t.h
new file mode 100644
index 0000000..e48019a
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-a83t.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Jean-Francois Moine <moinejf@free.fr>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN8I_A83T_H_
+#define _DT_BINDINGS_RST_SUN8I_A83T_H_
+
+#define RST_USB_PHY0		0
+#define RST_USB_PHY1		1
+#define RST_USB_HSIC		2
+
+#define RST_DRAM		3
+#define RST_MBUS		4
+
+#define RST_BUS_MIPI_DSI	5
+#define RST_BUS_CE		6
+#define RST_BUS_DMA		7
+#define RST_BUS_MMC0		8
+#define RST_BUS_MMC1		9
+#define RST_BUS_MMC2		10
+#define RST_BUS_NAND		11
+#define RST_BUS_DRAM		12
+#define RST_BUS_EMAC		13
+#define RST_BUS_HSTIMER		14
+#define RST_BUS_SPI0		15
+#define RST_BUS_SPI1		16
+#define RST_BUS_USBDRD		17
+#define RST_BUS_EHCI0		18
+#define RST_BUS_EHCI1		19
+#define RST_BUS_OHCI0		20
+#define RST_BUS_VE		21
+#define RST_BUS_TCON0		22
+#define RST_BUS_TCON1		23
+#define RST_BUS_CSI		24
+#define RST_BUS_HDMI0		25
+#define RST_BUS_HDMI1		26
+#define RST_BUS_DE		27
+#define RST_BUS_GPU		28
+#define RST_BUS_MSGBOX		29
+#define RST_BUS_SPINLOCK	30
+#define RST_BUS_LVDS		31
+#define RST_BUS_SPDIF		32
+#define RST_BUS_DAUDIO0		33
+#define RST_BUS_DAUDIO1		34
+#define RST_BUS_DAUDIO2		35
+#define RST_BUS_TDM		36
+#define RST_BUS_I2C0		37
+#define RST_BUS_I2C1		38
+#define RST_BUS_I2C2		39
+#define RST_BUS_UART0		40
+#define RST_BUS_UART1		41
+#define RST_BUS_UART2		42
+#define RST_BUS_UART3		43
+#define RST_BUS_UART4		44
+
+#endif /* _DT_BINDINGS_RST_SUN8I_A83T_H_ */
-- 
2.8.4

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

* [PATCH v2 3/3] dt: sun8i: Define the clocks of the A83T
  2016-06-11 17:39 [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks Jean-Francois Moine
  2016-06-11 16:23 ` [PATCH v2 1/3] clk: sunxi-ng: Add N-D-M-P-factor clock support Jean-Francois Moine
  2016-06-11 16:50 ` [PATCH v2 2/3] clk: sunxi-ng: Add the A83T clocks and resets Jean-Francois Moine
@ 2016-06-11 17:04 ` Jean-Francois Moine
       [not found] ` <CAEzqOZuGbn0Qc62mLpPKuH+n8doVLQec5Lg-cvT2C5tqh1GFzg@mail.gmail.com>
  3 siblings, 0 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2016-06-11 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

The clocks are defined by the CCU binding.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index d3473f8..4fec56a 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -45,9 +45,10 @@
 
 #include "skeleton.dtsi"
 
+#include <dt-bindings/clock/sun8i-a83t.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-
 #include <dt-bindings/pinctrl/sun4i-a10.h>
+#include <dt-bindings/reset/sun8i-a83t.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -138,13 +139,13 @@
 			clock-output-names = "osc16M";
 		};
 
-		osc16Md512: osc16Md512_clk {
+		osc32k: osc32k_clk {
 			#clock-cells = <0>;
 			compatible = "fixed-factor-clock";
 			clock-div = <512>;
 			clock-mult = <1>;
 			clocks = <&osc16M>;
-			clock-output-names = "osc16M-d512";
+			clock-output-names = "osc32k";
 		};
 	};
 
@@ -154,13 +155,20 @@
 		#size-cells = <1>;
 		ranges;
 
+		ccu: clock at 01c20000 {
+			compatible = "allwinner,sun8i-a83t-ccu";
+			reg = <0x01c20000 0x400>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
 		pio: pinctrl at 01c20800 {
 			compatible = "allwinner,sun8i-a83t-pinctrl";
 			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 			reg = <0x01c20800 0x400>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_BUS_PIO>;
 			gpio-controller;
 			interrupt-controller;
 			#interrupt-cells = <3>;
@@ -210,7 +218,7 @@
 			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&osc24M>;
+			clocks = <&ccu CLK_BUS_UART0>;
 			status = "disabled";
 		};
 
-- 
2.8.4

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

* [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks
@ 2016-06-11 17:39 Jean-Francois Moine
  2016-06-11 16:23 ` [PATCH v2 1/3] clk: sunxi-ng: Add N-D-M-P-factor clock support Jean-Francois Moine
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2016-06-11 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds the clocks of the sunxi A83T in the "modern"
clock framework proposed by Maxime Ripard.
It applies on the V2 of his patch series.

It is currently being tested on a Banana Pi M3 with the legacy u-boot.
- working:
	mmc0
	mmc2 (eMMC) but slow clock
	ths
	uart0
	usb0
- not working:
	mmc1 (wifi/bt)
	video (machine freeze on reading/writing the DE I/O memory)
- not yet tested
	audio
	prcm

Jean-Francois Moine (3):
  clk: sunxi-ng: Add N-D-M-P-factor clock support
  clk: sunxi-ng: Add the A83T clocks and resets
  dt: sun8i: Define the clocks of the A83T

 arch/arm/boot/dts/sun8i-a83t.dtsi      |  18 +-
 drivers/clk/sunxi-ng/Makefile          |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c  | 675 +++++++++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu_common.h      |   1 +
 drivers/clk/sunxi-ng/ccu_ndmp.c        | 239 ++++++++++++
 drivers/clk/sunxi-ng/ccu_ndmp.h        |  96 +++++
 include/dt-bindings/clock/sun8i-a83t.h | 150 ++++++++
 include/dt-bindings/reset/sun8i-a83t.h |  94 +++++
 8 files changed, 1270 insertions(+), 6 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
 create mode 100644 drivers/clk/sunxi-ng/ccu_ndmp.c
 create mode 100644 drivers/clk/sunxi-ng/ccu_ndmp.h
 create mode 100644 include/dt-bindings/clock/sun8i-a83t.h
 create mode 100644 include/dt-bindings/reset/sun8i-a83t.h

-- 
2.8.4

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

* [linux-sunxi] [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks
       [not found] ` <CAEzqOZuGbn0Qc62mLpPKuH+n8doVLQec5Lg-cvT2C5tqh1GFzg@mail.gmail.com>
@ 2016-08-22  6:28   ` Jean-Francois Moine
  0 siblings, 0 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2016-08-22  6:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 22 Aug 2016 02:23:51 +0800
Vishnu Patekar <vishnupatekar0510@gmail.com> wrote:

> Thanks for followup patches for a83t modern clock.
> 
> well, this patch series does not apply on sunxi/for-next.

Hi Vishnu,

This series is rather old!
Well, at this time, I was thinking that the 'modern' clock (aka
sunxi-ng) was a good thing, but, just after sending this series, I was
blocked, mainly because of the 'new timing' of the MMC clocks.
So, I rewrote and simplified the sunxi clock driver, and I submitted a
'ccu' patch which was refused by Maxime and Mike.

Actually, my 'ccu' driver is almost finished. The code is only 1200
lines in one file. It contains optimized computation of the clock
parameters, handles the H3 CPU frequency, the MMC 'new timing',
sigma-delta modulation for the audio PLL, the PRCM clocks and more.
The SoC specific tables (actually H3 and A83T) are about 10kB, but they
are defined as templates in .init.rodata, so that only the tables of the
current SoC remain in memory after system init.

This driver works fine for my Allwinner's boards and I will never go
back to the 'sunxi-ng' which is rather complex and lacks of flexibility.
If you are interested, the source is available in my site (see below).

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

end of thread, other threads:[~2016-08-22  6:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-11 17:39 [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks Jean-Francois Moine
2016-06-11 16:23 ` [PATCH v2 1/3] clk: sunxi-ng: Add N-D-M-P-factor clock support Jean-Francois Moine
2016-06-11 16:50 ` [PATCH v2 2/3] clk: sunxi-ng: Add the A83T clocks and resets Jean-Francois Moine
2016-06-11 17:04 ` [PATCH v2 3/3] dt: sun8i: Define the clocks of the A83T Jean-Francois Moine
     [not found] ` <CAEzqOZuGbn0Qc62mLpPKuH+n8doVLQec5Lg-cvT2C5tqh1GFzg@mail.gmail.com>
2016-08-22  6:28   ` [linux-sunxi] [PATCH v2 0/3] clk: sunxi-ng: Add the A83T clocks Jean-Francois Moine

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