linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 00/10] add clock driver for Spreadtrum platforms
@ 2017-07-11 10:56 Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 01/10] drivers: move clock common macros out from vendor directories Chunyan Zhang
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

This is a rewrite of Spreadtrum's original clock driver[1] according to the
comments[2] from Stephen Boyd.

This series adds Spreadtrum clock support together with its binding
documentation and devicetree data.

Any comments would be greatly appreciated.

Thanks,
Chunyan

Changes from V1 (https://lkml.org/lkml/2017/6/17/356):
* Address Stephen's comments:
  - Switch to use platform device driver instead of the DT probing mechanism.
  - Move the common clock macro out from vendor directory, but need to remove those
    overlap code from other vendors (such as sunxi-ng) once this gets merged.
  - Add support to be built as a module.
  - Add 'sprd_' prefix for all spin locks used in these drivers.
  - Mark input parameter of sprd_x with const.
  - Remove unreasonable dependencies to CONFIG_64BIT.
  - Add readl() after writing the same register.
  - Remove CLK_IS_BASIC which is no longer used.
  - Remove unnecessary CLK_IGNORE_UNUSED when defining a clock.
  - Change to expose all clock index.
  - Use clk_ instead of ccu.
  - Add Kconfig for sprd clocks.
  - Move the fixed clocks out from the soc node.
  - Switch to use 64-bit math in pll driver instead of 32-bit math.
* Revise binding documentation according to dt modification.
* Rename sc9860.c to sc9860-clk.c


[1] https://lwn.net/Articles/722739/
[2] https://www.spinics.net/lists/arm-kernel/msg582017.html


Chunyan Zhang (10):
  drivers: move clock common macros out from vendor directories
  dt-bindings: Add Spreadtrum clock binding documentation
  clk: sprd: Add common infrastructure
  clk: sprd: add gate clock support
  clk: sprd: add mux clock support
  clk: sprd: add divider clock support
  clk: sprd: add composite clock support
  clk: sprd: add adjustable pll support
  clk: sprd: add clocks support for SC9860
  arm64: dts: add clocks for SC9860

 Documentation/devicetree/bindings/clock/sprd.txt |   36 +
 arch/arm64/boot/dts/sprd/sc9860.dtsi             |   22 +
 arch/arm64/boot/dts/sprd/whale2.dtsi             |    3 +-
 drivers/clk/Kconfig                              |    1 +
 drivers/clk/Makefile                             |    1 +
 drivers/clk/clk_common.h                         |   60 +
 drivers/clk/sprd/Kconfig                         |   14 +
 drivers/clk/sprd/Makefile                        |   11 +
 drivers/clk/sprd/common.c                        |   83 ++
 drivers/clk/sprd/common.h                        |   56 +
 drivers/clk/sprd/composite.c                     |   64 +
 drivers/clk/sprd/composite.h                     |   47 +
 drivers/clk/sprd/div.c                           |   98 ++
 drivers/clk/sprd/div.h                           |   77 +
 drivers/clk/sprd/gate.c                          |  104 ++
 drivers/clk/sprd/gate.h                          |   58 +
 drivers/clk/sprd/mux.c                           |   86 ++
 drivers/clk/sprd/mux.h                           |   63 +
 drivers/clk/sprd/pll.c                           |  236 +++
 drivers/clk/sprd/pll.h                           |  133 ++
 drivers/clk/sprd/sc9860-clk.c                    | 1726 ++++++++++++++++++++++
 include/dt-bindings/clock/sprd,sc9860-clk.h      |  375 +++++
 22 files changed, 3352 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
 create mode 100644 drivers/clk/clk_common.h
 create mode 100644 drivers/clk/sprd/Kconfig
 create mode 100644 drivers/clk/sprd/Makefile
 create mode 100644 drivers/clk/sprd/common.c
 create mode 100644 drivers/clk/sprd/common.h
 create mode 100644 drivers/clk/sprd/composite.c
 create mode 100644 drivers/clk/sprd/composite.h
 create mode 100644 drivers/clk/sprd/div.c
 create mode 100644 drivers/clk/sprd/div.h
 create mode 100644 drivers/clk/sprd/gate.c
 create mode 100644 drivers/clk/sprd/gate.h
 create mode 100644 drivers/clk/sprd/mux.c
 create mode 100644 drivers/clk/sprd/mux.h
 create mode 100644 drivers/clk/sprd/pll.c
 create mode 100644 drivers/clk/sprd/pll.h
 create mode 100644 drivers/clk/sprd/sc9860-clk.c
 create mode 100644 include/dt-bindings/clock/sprd,sc9860-clk.h

-- 
2.7.4

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

* [PATCH V2 01/10] drivers: move clock common macros out from vendor directories
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation Chunyan Zhang
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

These macros are used by more than one SoC vendor platforms, avoid to
have many copies of these code, this patch moves them to the common
clock directory which every clock drivers can access to.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/clk_common.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 drivers/clk/clk_common.h

diff --git a/drivers/clk/clk_common.h b/drivers/clk/clk_common.h
new file mode 100644
index 0000000..21e93d2
--- /dev/null
+++ b/drivers/clk/clk_common.h
@@ -0,0 +1,60 @@
+/*
+ * drivers/clk/clk_common.h
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _CLK_COMMON_H_
+#define _CLK_COMMON_H_
+
+#include <linux/clk-provider.h>
+
+#define CLK_HW_INIT(_name, _parent, _ops, _flags)		\
+	(&(struct clk_init_data) {				\
+		.flags		= _flags,			\
+		.name		= _name,			\
+		.parent_names	= (const char *[]) { _parent },	\
+		.num_parents	= 1,				\
+		.ops		= _ops,				\
+	})
+
+#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags)	\
+	(&(struct clk_init_data) {				\
+		.flags		= _flags,			\
+		.name		= _name,			\
+		.parent_names	= _parents,			\
+		.num_parents	= ARRAY_SIZE(_parents),		\
+		.ops		= _ops,				\
+	})
+
+#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags)     \
+	(&(struct clk_init_data) {                      \
+		.flags          = _flags,               \
+		.name           = _name,                \
+		.parent_names   = NULL,                 \
+		.num_parents    = 0,                    \
+		.ops            = _ops,                 \
+	})
+
+#define CLK_FIXED_FACTOR(_struct, _name, _parent,			\
+			_div, _mult, _flags)				\
+	struct clk_fixed_factor _struct = {				\
+		.div		= _div,					\
+		.mult		= _mult,				\
+		.hw.init	= CLK_HW_INIT(_name,			\
+					      _parent,			\
+					      &clk_fixed_factor_ops,	\
+					      _flags),			\
+	}
+
+#define CLK_FIXED_RATE(_struct, _name, _flags,				\
+		       _fixed_rate, _fixed_accuracy)			\
+	struct clk_fixed_rate _struct = {				\
+		.fixed_rate	= _fixed_rate,				\
+		.fixed_accuracy	= _fixed_accuracy,			\
+		.hw.init	= CLK_HW_INIT_NO_PARENT(_name,		\
+					  &clk_fixed_rate_ops,		\
+							_flags),	\
+	}
+
+#endif /* _CLK_COMMON_H_ */
-- 
2.7.4

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

* [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 01/10] drivers: move clock common macros out from vendor directories Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-14 16:10   ` Rob Herring
  2017-07-21 22:57   ` Stephen Boyd
  2017-07-11 10:56 ` [PATCH V2 03/10] clk: sprd: Add common infrastructure Chunyan Zhang
                   ` (7 subsequent siblings)
  9 siblings, 2 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce a new binding with its documentation for Spreadtrum clock
sub-framework.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 Documentation/devicetree/bindings/clock/sprd.txt | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt

diff --git a/Documentation/devicetree/bindings/clock/sprd.txt b/Documentation/devicetree/bindings/clock/sprd.txt
new file mode 100644
index 0000000..c6f3abf
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sprd.txt
@@ -0,0 +1,36 @@
+Spreadtrum Clock Binding
+------------------------
+
+Required properties:
+- compatible: must contain the following compatible:
+	- "sprd,sc9860-clk" (only support SC9860 for the time being)
+
+- reg:	Must contain the registers base address and length.
+	Clocks on most of Spreadtrum's SoCs were designed to locate in a few
+	different address areas, so there would be more than one items under
+	this property.
+
+- #clock-cells: must be 1
+
+Example:
+
+clk: clk {
+	compatible = "sprd,sc9860-clk";
+	#clock-cells = <1>;
+	reg = <0 0x20000000 0 0x400>,
+	      <0 0x20210000 0 0x3000>,
+	      <0 0x402b0000 0 0x4000>,
+	      <0 0x402d0000 0 0x400>,
+	      <0 0x402e0000 0 0x4000>,
+	      <0 0x40400000 0 0x400>,
+	      <0 0x40880000 0 0x400>,
+	      <0 0x415e0000 0 0x400>,
+	      <0 0x60200000 0 0x400>,
+	      <0 0x61000000 0 0x400>,
+	      <0 0x61100000 0 0x3000>,
+	      <0 0x62000000 0 0x4000>,
+	      <0 0x62100000 0 0x4000>,
+	      <0 0x63000000 0 0x400>,
+	      <0 0x63100000 0 0x3000>,
+	      <0 0x70b00000 0 0x3000>;
+};
-- 
2.7.4

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

* [PATCH V2 03/10] clk: sprd: Add common infrastructure
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 01/10] drivers: move clock common macros out from vendor directories Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 04/10] clk: sprd: add gate clock support Chunyan Zhang
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Added Spreadtrum's clock driver framework together with common
structures and interface functions.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/Kconfig       |  1 +
 drivers/clk/Makefile      |  1 +
 drivers/clk/sprd/Kconfig  |  4 +++
 drivers/clk/sprd/Makefile |  3 ++
 drivers/clk/sprd/common.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/common.h | 56 ++++++++++++++++++++++++++++++++
 6 files changed, 148 insertions(+)
 create mode 100644 drivers/clk/sprd/Kconfig
 create mode 100644 drivers/clk/sprd/Makefile
 create mode 100644 drivers/clk/sprd/common.c
 create mode 100644 drivers/clk/sprd/common.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 36cfea3..baf1688 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -225,6 +225,7 @@ source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/samsung/Kconfig"
+source "drivers/clk/sprd/Kconfig"
 source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c19983a..1d62721 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
 obj-$(CONFIG_ARCH_SIRF)			+= sirf/
 obj-$(CONFIG_ARCH_SOCFPGA)		+= socfpga/
 obj-$(CONFIG_PLAT_SPEAR)		+= spear/
+obj-$(CONFIG_ARCH_SPRD)			+= sprd/
 obj-$(CONFIG_ARCH_STI)			+= st/
 obj-$(CONFIG_ARCH_SUNXI)		+= sunxi/
 obj-$(CONFIG_ARCH_SUNXI)		+= sunxi-ng/
diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
new file mode 100644
index 0000000..67a3287
--- /dev/null
+++ b/drivers/clk/sprd/Kconfig
@@ -0,0 +1,4 @@
+config SPRD_COMMON_CLK
+	tristate "Clock support for Spreadtrum SoCs"
+	depends on ARCH_SPRD || COMPILE_TEST
+	default ARCH_SPRD
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
new file mode 100644
index 0000000..74f4b80
--- /dev/null
+++ b/drivers/clk/sprd/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SPRD_COMMON_CLK)	+= clk-sprd.o
+
+clk-sprd-y	+= common.o
diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c
new file mode 100644
index 0000000..5ff0473
--- /dev/null
+++ b/drivers/clk/sprd/common.c
@@ -0,0 +1,83 @@
+/*
+ * Spreadtrum clock infrastructure
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/module.h>
+
+#include "common.h"
+
+static inline void __iomem *clk_find_base(const struct clk_addr_map *maps,
+					  unsigned int num, unsigned int reg)
+{
+	int i;
+
+	for (i = 0; i < num; i++)
+		if ((reg & 0xffff0000) == maps[i].phy)
+			return maps[i].virt;
+
+	return 0;
+}
+
+int sprd_clk_probe(struct device_node *node, const struct clk_addr_map *maps,
+		   unsigned int count, const struct sprd_clk_desc *desc)
+{
+	int i, ret = 0;
+	struct sprd_clk_common *cclk;
+	struct clk_hw *hw;
+
+	for (i = 0; i < desc->num_clk_clks; i++) {
+		cclk = desc->clk_clks[i];
+		if (!cclk)
+			continue;
+
+		cclk->base = clk_find_base(maps, count, cclk->reg);
+		if (!cclk->base) {
+			pr_err("%s: No mapped address found for clock(0x%x)\n",
+				__func__, cclk->reg);
+			return -EINVAL;
+		}
+		cclk->reg = cclk->reg & 0xffff;
+	}
+
+	for (i = 0; i < desc->hw_clks->num; i++) {
+
+		hw = desc->hw_clks->hws[i];
+
+		if (!hw)
+			continue;
+
+		ret = clk_hw_register(NULL, hw);
+		if (ret) {
+			pr_err("Couldn't register clock %d - %s\n",
+			       i, hw->init->name);
+			goto err_clk_unreg;
+		}
+	}
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+				     desc->hw_clks);
+	if (ret) {
+		pr_err("Failed to add clock provider.\n");
+		goto err_clk_unreg;
+	}
+
+	return 0;
+
+err_clk_unreg:
+	while (--i >= 0) {
+		hw = desc->hw_clks->hws[i];
+		if (!hw)
+			continue;
+
+		clk_hw_unregister(hw);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sprd_clk_probe);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/sprd/common.h b/drivers/clk/sprd/common.h
new file mode 100644
index 0000000..c747a7d
--- /dev/null
+++ b/drivers/clk/sprd/common.h
@@ -0,0 +1,56 @@
+/*
+ * Spreadtrum clock infrastructure
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_CLK_COMMON_H_
+#define _SPRD_CLK_COMMON_H_
+
+#include <linux/clk-provider.h>
+
+#include "../clk_common.h"
+
+struct device_node;
+
+struct sprd_clk_common {
+	void __iomem	*base;
+	u32		reg;
+	spinlock_t	*lock;
+	struct clk_hw	hw;
+};
+
+struct clk_addr_map {
+	phys_addr_t phy;
+	void __iomem *virt;
+};
+
+static inline u32 sprd_clk_readl(const struct sprd_clk_common *common)
+{
+	return readl(common->base + common->reg);
+}
+
+static inline void sprd_clk_writel(u32 val,
+				   const struct sprd_clk_common *common)
+{
+	writel(val, common->base + common->reg);
+}
+
+static inline struct sprd_clk_common *
+	hw_to_sprd_clk_common(const struct clk_hw *hw)
+{
+	return container_of(hw, struct sprd_clk_common, hw);
+}
+
+struct sprd_clk_desc {
+	struct sprd_clk_common		**clk_clks;
+	unsigned long			num_clk_clks;
+	struct clk_hw_onecell_data	*hw_clks;
+};
+
+int sprd_clk_probe(struct device_node *node, const struct clk_addr_map *maps,
+		   unsigned int count, const struct sprd_clk_desc *desc);
+
+#endif /* _SPRD_CLK_COMMON_H_ */
-- 
2.7.4

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

* [PATCH V2 04/10] clk: sprd: add gate clock support
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (2 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 03/10] clk: sprd: Add common infrastructure Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 05/10] clk: sprd: add mux " Chunyan Zhang
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Some clocks on the Spreadtrum's SoCs are just simple gates. Add
support for those clocks.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/gate.c   | 104 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/gate.h   |  58 ++++++++++++++++++++++++++
 3 files changed, 163 insertions(+)
 create mode 100644 drivers/clk/sprd/gate.c
 create mode 100644 drivers/clk/sprd/gate.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 74f4b80..8cd5592 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SPRD_COMMON_CLK)	+= clk-sprd.o
 
 clk-sprd-y	+= common.o
+clk-sprd-y	+= gate.o
diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c
new file mode 100644
index 0000000..aa56b2b
--- /dev/null
+++ b/drivers/clk/sprd/gate.c
@@ -0,0 +1,104 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+
+#include "gate.h"
+
+DEFINE_SPINLOCK(sprd_gate_lock);
+EXPORT_SYMBOL_GPL(sprd_gate_lock);
+
+static void sprd_gate_endisable(const struct sprd_gate *sg, u32 en)
+{
+	const struct sprd_clk_common *common = &sg->common;
+	unsigned long flags = 0;
+	u32 reg;
+	int set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+
+	set ^= en;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	reg = sprd_clk_readl(common);
+
+	if (set)
+		reg |= sg->op_bit;
+	else
+		reg &= ~sg->op_bit;
+
+	sprd_clk_writel(reg, common);
+
+	spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void clk_sc_gate_endisable(const struct sprd_gate *sg, u32 en)
+{
+	const struct sprd_clk_common *common = &sg->common;
+	unsigned long flags = 0;
+	int set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+	u32 offset;
+
+	set ^= en;
+
+	/*
+	 * Each set/clear gate clock has three registers:
+	 * common->reg			- base register
+	 * common->reg + offset		- set register
+	 * common->reg + 2 * offset	- clear register
+	 */
+	offset = set ? sg->sc_offset : sg->sc_offset * 2;
+
+	spin_lock_irqsave(common->lock, flags);
+	sprd_clk_writel_offset(sg->op_bit, common, offset);
+	spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void sprd_gate_disable(struct clk_hw *hw)
+{
+	struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+	if (sg->sc_offset)
+		clk_sc_gate_endisable(sg, 0);
+	else
+		sprd_gate_endisable(sg, 0);
+}
+
+static int sprd_gate_enable(struct clk_hw *hw)
+{
+	struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+	if (sg->sc_offset)
+		clk_sc_gate_endisable(sg, 1);
+	else
+		sprd_gate_endisable(sg, 1);
+
+	return 0;
+}
+
+static int sprd_gate_is_enabled(struct clk_hw *hw)
+{
+	struct sprd_gate *sg = hw_to_sprd_gate(hw);
+	struct sprd_clk_common *common = &sg->common;
+	u32 reg;
+
+	reg = sprd_clk_readl(common);
+
+	if (sg->flags & CLK_GATE_SET_TO_DISABLE)
+		reg ^= sg->op_bit;
+
+	reg &= sg->op_bit;
+
+	return reg ? 1 : 0;
+}
+
+const struct clk_ops sprd_gate_ops = {
+	.disable	= sprd_gate_disable,
+	.enable		= sprd_gate_enable,
+	.is_enabled	= sprd_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(sprd_gate_ops);
diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h
new file mode 100644
index 0000000..7fb4e49
--- /dev/null
+++ b/drivers/clk/sprd/gate.h
@@ -0,0 +1,58 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_GATE_H_
+#define _SPRD_GATE_H_
+
+#include "common.h"
+
+struct sprd_gate {
+	u32			op_bit;
+	u16			flags;
+	u16			sc_offset;
+
+	struct sprd_clk_common	common;
+};
+
+#define SPRD_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset,	\
+		      _op_bit, _flags, _gate_flags)			\
+	struct sprd_gate _struct = {					\
+		.op_bit		= _op_bit,				\
+		.sc_offset	= _sc_offset,				\
+		.flags		= _gate_flags,				\
+		.common	= {						\
+			.reg		= _reg,				\
+			.lock		= &sprd_gate_lock,		\
+			.hw.init	= CLK_HW_INIT(_name,		\
+						      _parent,		\
+						      &sprd_gate_ops,	\
+						      _flags),		\
+		}							\
+	}
+
+static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw)
+{
+	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+	return container_of(common, struct sprd_gate, common);
+}
+
+static inline void sprd_clk_writel_offset(u32 val,
+	const struct sprd_clk_common *common, u32 offset)
+{
+	writel(val, common->base + common->reg + offset);
+}
+
+void sprd_gate_helper_disable(struct sprd_clk_common *common, u32 gate);
+int sprd_gate_helper_enable(struct sprd_clk_common *common, u32 gate);
+int sprd_gate_helper_is_enabled(struct sprd_clk_common *common, u32 gate);
+
+extern const struct clk_ops sprd_gate_ops;
+extern spinlock_t sprd_gate_lock;
+
+#endif /* _SPRD_GATE_H_ */
-- 
2.7.4

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

* [PATCH V2 05/10] clk: sprd: add mux clock support
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (3 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 04/10] clk: sprd: add gate clock support Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 06/10] clk: sprd: add divider " Chunyan Zhang
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds clock multiplexor support for Spreadtrum platforms,
the mux clocks also can be found in sprd composite clocks, so
provides two helpers that can be reused later on.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Makefile |  1 +
 drivers/clk/sprd/mux.c    | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/mux.h    | 63 ++++++++++++++++++++++++++++++++++
 3 files changed, 150 insertions(+)
 create mode 100644 drivers/clk/sprd/mux.c
 create mode 100644 drivers/clk/sprd/mux.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 8cd5592..cee36b5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)	+= clk-sprd.o
 
 clk-sprd-y	+= common.o
 clk-sprd-y	+= gate.o
+clk-sprd-y	+= mux.o
diff --git a/drivers/clk/sprd/mux.c b/drivers/clk/sprd/mux.c
new file mode 100644
index 0000000..b5d8988
--- /dev/null
+++ b/drivers/clk/sprd/mux.c
@@ -0,0 +1,86 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#include "mux.h"
+
+DEFINE_SPINLOCK(sprd_mux_lock);
+EXPORT_SYMBOL_GPL(sprd_mux_lock);
+
+u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
+			      const struct sprd_mux_internal *mux)
+{
+	u32 reg;
+	u8 parent;
+	int num_parents;
+	int i;
+
+	reg = sprd_clk_readl(common);
+	parent = reg >> mux->shift;
+	parent &= (1 << mux->width) - 1;
+
+	if (mux->table) {
+		num_parents = clk_hw_get_num_parents(&common->hw);
+
+		for (i = 0; i < num_parents; i++)
+			if (parent == mux->table[i] ||
+			    (i < (num_parents - 1) && parent > mux->table[i] &&
+			     parent < mux->table[i + 1]))
+				return i;
+		if (i == num_parents)
+			return i - 1;
+	}
+
+	return parent;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
+
+static u8 sprd_mux_get_parent(struct clk_hw *hw)
+{
+	struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+	return sprd_mux_helper_get_parent(&cm->common, &cm->mux);
+}
+
+int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
+			       const struct sprd_mux_internal *mux,
+			       u8 index)
+{
+	unsigned long flags = 0;
+	u32 reg;
+
+	if (mux->table)
+		index = mux->table[index];
+
+	spin_lock_irqsave(common->lock, flags);
+
+	reg = sprd_clk_readl(common);
+	reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
+	sprd_clk_writel(reg | (index << mux->shift), common);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
+
+static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+	return sprd_mux_helper_set_parent(&cm->common, &cm->mux, index);
+}
+
+const struct clk_ops sprd_mux_ops = {
+	.get_parent = sprd_mux_get_parent,
+	.set_parent = sprd_mux_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_mux_ops);
diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h
new file mode 100644
index 0000000..aa35514
--- /dev/null
+++ b/drivers/clk/sprd/mux.h
@@ -0,0 +1,63 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_MUX_H_
+#define _SPRD_MUX_H_
+
+#include "common.h"
+
+struct sprd_mux_internal {
+	u8		shift;
+	u8		width;
+	const u8	*table;
+};
+
+struct sprd_mux {
+	struct sprd_mux_internal mux;
+	struct sprd_clk_common	common;
+};
+
+#define _SPRD_MUX_CLK(_shift, _width, _table)		\
+	{						\
+		.shift	= _shift,			\
+		.width	= _width,			\
+		.table	= _table,			\
+	}
+
+#define SPRD_MUX_CLK(_struct, _name, _parents, _table,			\
+				     _reg, _shift, _width,		\
+				     _flags)				\
+	struct sprd_mux _struct = {					\
+		.mux	= _SPRD_MUX_CLK(_shift, _width, _table),	\
+		.common	= {						\
+			.reg		= _reg,				\
+			.lock		= &sprd_mux_lock,		\
+			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
+							      _parents, \
+							      &sprd_mux_ops,\
+							      _flags),	\
+		}							\
+	}
+
+static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw)
+{
+	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+	return container_of(common, struct sprd_mux, common);
+}
+
+extern const struct clk_ops sprd_mux_ops;
+extern spinlock_t sprd_mux_lock;
+
+u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
+			      const struct sprd_mux_internal *mux);
+int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
+			       const struct sprd_mux_internal *mux,
+			       u8 index);
+
+#endif /* _SPRD_MUX_H_ */
-- 
2.7.4

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

* [PATCH V2 06/10] clk: sprd: add divider clock support
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (4 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 05/10] clk: sprd: add mux " Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 07/10] clk: sprd: add composite " Chunyan Zhang
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

This is a feature that can also be found in sprd composite clocks,
provide a bunch of helpers that can be reused later on.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Makefile |  1 +
 drivers/clk/sprd/div.c    | 98 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/div.h    | 77 +++++++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)
 create mode 100644 drivers/clk/sprd/div.c
 create mode 100644 drivers/clk/sprd/div.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index cee36b5..80e6039 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)	+= clk-sprd.o
 clk-sprd-y	+= common.o
 clk-sprd-y	+= gate.o
 clk-sprd-y	+= mux.o
+clk-sprd-y	+= div.o
diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c
new file mode 100644
index 0000000..8ba6642
--- /dev/null
+++ b/drivers/clk/sprd/div.c
@@ -0,0 +1,98 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+
+#include "div.h"
+
+DEFINE_SPINLOCK(sprd_div_lock);
+EXPORT_SYMBOL_GPL(sprd_div_lock);
+
+long sprd_div_helper_round_rate(struct sprd_clk_common *common,
+				const struct sprd_div_internal *div,
+				unsigned long rate,
+				unsigned long *parent_rate)
+{
+	return divider_round_rate(&common->hw, rate, parent_rate,
+				  NULL, div->width, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
+
+static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	struct sprd_div *cd = hw_to_sprd_div(hw);
+
+	return sprd_div_helper_round_rate(&cd->common, &cd->div,
+					  rate, parent_rate);
+}
+
+unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
+					  const struct sprd_div_internal *div,
+					  unsigned long parent_rate)
+{
+	unsigned long val;
+	u32 reg;
+
+	reg = sprd_clk_readl(common);
+	val = reg >> div->shift;
+	val &= (1 << div->width) - 1;
+
+	return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
+
+static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct sprd_div *cd = hw_to_sprd_div(hw);
+
+	return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate);
+}
+
+int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
+			     const struct sprd_div_internal *div,
+			     unsigned long rate,
+			     unsigned long parent_rate)
+{
+	unsigned long flags;
+	unsigned long val;
+	u32 reg;
+
+	val = divider_get_val(rate, parent_rate, NULL,
+			      div->width, 0);
+
+	spin_lock_irqsave(common->lock, flags);
+
+	reg = sprd_clk_readl(common);
+	reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
+
+	sprd_clk_writel(reg | (val << div->shift), common);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
+
+static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct sprd_div *cd = hw_to_sprd_div(hw);
+
+	return sprd_div_helper_set_rate(&cd->common, &cd->div,
+					rate, parent_rate);
+}
+
+const struct clk_ops sprd_div_ops = {
+	.recalc_rate = sprd_div_recalc_rate,
+	.round_rate = sprd_div_round_rate,
+	.set_rate = sprd_div_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_div_ops);
diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
new file mode 100644
index 0000000..128348e
--- /dev/null
+++ b/drivers/clk/sprd/div.h
@@ -0,0 +1,77 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_DIV_H_
+#define _SPRD_DIV_H_
+
+#include "common.h"
+
+/**
+ * struct sprd_div_internal - Internal divider description
+ * @shift: Bit offset of the divider in its register
+ * @width: Width of the divider field in its register
+ *
+ * That structure represents a single divider, and is meant to be
+ * embedded in other structures representing the various clock
+ * classes.
+ */
+struct sprd_div_internal {
+	u8	shift;
+	u8	width;
+};
+
+#define _SPRD_DIV_CLK(_shift, _width)	\
+	{				\
+		.shift	= _shift,	\
+		.width	= _width,	\
+	}
+
+struct sprd_div {
+	struct sprd_div_internal	div;
+	struct sprd_clk_common	common;
+};
+
+#define SPRD_DIV_CLK(_struct, _name, _parent, _reg,			\
+			_shift, _width, _flags)				\
+	struct sprd_div _struct = {					\
+		.div	= _SPRD_DIV_CLK(_shift, _width),		\
+		.common	= {						\
+			.reg		= _reg,				\
+			.lock		= &sprd_div_lock,		\
+			.hw.init	= CLK_HW_INIT(_name,		\
+						      _parent,		\
+						      &sprd_div_ops,	\
+						      _flags),		\
+		}							\
+	}
+
+static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
+{
+	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+	return container_of(common, struct sprd_div, common);
+}
+
+long sprd_div_helper_round_rate(struct sprd_clk_common *common,
+				const struct sprd_div_internal *div,
+				unsigned long rate,
+				unsigned long *parent_rate);
+
+unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
+					  const struct sprd_div_internal *div,
+					  unsigned long parent_rate);
+
+int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
+			     const struct sprd_div_internal *div,
+			     unsigned long rate,
+			     unsigned long parent_rate);
+
+extern const struct clk_ops sprd_div_ops;
+extern spinlock_t sprd_div_lock;
+
+#endif /* _SPRD_DIV_H_ */
-- 
2.7.4

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

* [PATCH V2 07/10] clk: sprd: add composite clock support
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (5 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 06/10] clk: sprd: add divider " Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 08/10] clk: sprd: add adjustable pll support Chunyan Zhang
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduced composite driveri for Spreadtrum's SoCs. The
functions of this composite clock simply consist of divider and
mux clocks.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Makefile    |  1 +
 drivers/clk/sprd/composite.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/composite.h | 47 ++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+)
 create mode 100644 drivers/clk/sprd/composite.c
 create mode 100644 drivers/clk/sprd/composite.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 80e6039..2262e76 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -4,3 +4,4 @@ clk-sprd-y	+= common.o
 clk-sprd-y	+= gate.o
 clk-sprd-y	+= mux.o
 clk-sprd-y	+= div.o
+clk-sprd-y	+= composite.o
diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
new file mode 100644
index 0000000..25b045d
--- /dev/null
+++ b/drivers/clk/sprd/composite.c
@@ -0,0 +1,64 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+
+#include "composite.h"
+
+DEFINE_SPINLOCK(sprd_comp_lock);
+EXPORT_SYMBOL_GPL(sprd_comp_lock);
+
+static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+	return sprd_div_helper_round_rate(&cc->common, &cc->div,
+					 rate, parent_rate);
+}
+
+static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+	return sprd_div_helper_recalc_rate(&cc->common, &cc->div, parent_rate);
+}
+
+static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+	return sprd_div_helper_set_rate(&cc->common, &cc->div,
+				       rate, parent_rate);
+}
+
+static u8 sprd_comp_get_parent(struct clk_hw *hw)
+{
+	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+	return sprd_mux_helper_get_parent(&cc->common, &cc->mux);
+}
+
+static int sprd_comp_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+	return sprd_mux_helper_set_parent(&cc->common, &cc->mux, index);
+}
+
+const struct clk_ops sprd_comp_ops = {
+	.get_parent	= sprd_comp_get_parent,
+	.set_parent	= sprd_comp_set_parent,
+
+	.round_rate	= sprd_comp_round_rate,
+	.recalc_rate	= sprd_comp_recalc_rate,
+	.set_rate	= sprd_comp_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_comp_ops);
diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h
new file mode 100644
index 0000000..f5ca0c9
--- /dev/null
+++ b/drivers/clk/sprd/composite.h
@@ -0,0 +1,47 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_COMPOSITE_H_
+#define _SPRD_COMPOSITE_H_
+
+#include "common.h"
+#include "mux.h"
+#include "div.h"
+
+struct sprd_comp {
+	struct sprd_mux_internal	mux;
+	struct sprd_div_internal	div;
+	struct sprd_clk_common	common;
+};
+
+#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _table,		\
+			_mshift, _mwidth, _dshift, _dwidth, _flags)	\
+	struct sprd_comp _struct = {					\
+		.mux	= _SPRD_MUX_CLK(_mshift, _mwidth, _table),	\
+		.div	= _SPRD_DIV_CLK(_dshift, _dwidth),		\
+		.common = {						\
+			 .reg		= _reg,				\
+			 .lock		= &sprd_comp_lock,		\
+			 .hw.init	= CLK_HW_INIT_PARENTS(_name,	\
+							      _parent,	\
+							&sprd_comp_ops,	\
+							      _flags),	\
+			 }						\
+	}
+
+static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
+{
+	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+	return container_of(common, struct sprd_comp, common);
+}
+
+extern const struct clk_ops sprd_comp_ops;
+extern spinlock_t sprd_comp_lock;
+
+#endif /* _SPRD_COMPOSITE_H_ */
-- 
2.7.4

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

* [PATCH V2 08/10] clk: sprd: add adjustable pll support
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (6 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 07/10] clk: sprd: add composite " Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 09/10] clk: sprd: add clocks support for SC9860 Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 10/10] arm64: dts: add clocks " Chunyan Zhang
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Introduced a common adjustable pll clock driver for Spreadtrum SoCs.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/pll.c    | 236 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sprd/pll.h    | 133 ++++++++++++++++++++++++++
 3 files changed, 370 insertions(+)
 create mode 100644 drivers/clk/sprd/pll.c
 create mode 100644 drivers/clk/sprd/pll.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 2262e76..d693969 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -5,3 +5,4 @@ clk-sprd-y	+= gate.o
 clk-sprd-y	+= mux.o
 clk-sprd-y	+= div.o
 clk-sprd-y	+= composite.o
+clk-sprd-y	+= pll.o
diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c
new file mode 100644
index 0000000..97935a2
--- /dev/null
+++ b/drivers/clk/sprd/pll.c
@@ -0,0 +1,236 @@
+/*
+ * Spreadtrum pll clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "pll.h"
+
+#define CLK_PLL_1M	1000000
+#define CLK_PLL_10M	(CLK_PLL_1M * 10)
+
+#define pindex(pll, member)		\
+	(pll->factors[member].shift / (8 * sizeof(pll->regs[0])))
+
+#define pshift(pll, member)		\
+	(pll->factors[member].shift % (8 * sizeof(pll->regs[0])))
+
+#define pwidth(pll, member)		\
+	pll->factors[member].width
+
+#define pmask(pll, member)					\
+	((pwidth(pll, member)) ?				\
+	GENMASK(pwidth(pll, member) + pshift(pll, member) - 1,	\
+	pshift(pll, member)) : 0)
+
+#define pinternal(pll, cfg, member)	\
+	(cfg[pindex(pll, member)] & pmask(pll, member))
+
+#define pinternal_val(pll, cfg, member)	\
+	(pinternal(pll, cfg, member) >> pshift(pll, member))
+
+static unsigned long pll_get_refin(const struct sprd_pll *pll)
+{
+	u32 shift, mask, index, refin_id = 3;
+	const unsigned long refin[4] = { 2, 4, 13, 26 };
+
+	if (pwidth(pll, PLL_REFIN)) {
+		index = pindex(pll, PLL_REFIN);
+		shift = pshift(pll, PLL_REFIN);
+		mask = pmask(pll, PLL_REFIN);
+		refin_id = (sprd_pll_readl(pll, index) & mask) >> shift;
+		if (refin_id > 3)
+			refin_id = 3;
+	}
+
+	return refin[refin_id];
+}
+
+static u32 pll_get_ibias(u64 rate, const u64 *table)
+{
+	u32 i, num = table[0];
+
+	for (i = 1; i < num + 1; i++)
+		if (rate <= table[i])
+			break;
+
+	return (i == num + 1) ? num : i;
+}
+
+static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
+					   unsigned long parent_rate)
+{
+	u32 *cfg;
+	u32 i, mask, reg_num = pll->regs[0];
+	unsigned long rate, nint, kint = 0;
+	u64 refin;
+	u16 k1, k2;
+
+	cfg = kcalloc(reg_num, sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	for (i = 0; i < reg_num; i++)
+		cfg[i] = sprd_pll_readl(pll, i);
+
+	refin = pll_get_refin(pll);
+
+	if (pinternal(pll, cfg, PLL_PREDIV))
+		refin = refin * 2;
+
+	if (pwidth(pll, PLL_POSTDIV) &&
+	    ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
+	     (!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV))))
+		refin = refin / 2;
+
+	if (!pinternal(pll, cfg, PLL_DIV_S)) {
+		rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
+	} else {
+		nint = pinternal_val(pll, cfg, PLL_NINT);
+		if (pinternal(pll, cfg, PLL_SDM_EN))
+			kint = pinternal_val(pll, cfg, PLL_KINT);
+
+		mask = pmask(pll, PLL_KINT);
+
+		k1 = pll->k1;
+		k2 = pll->k2;
+		rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
+					 ((mask >> __ffs(mask)) + 1)) *
+					 k2 + refin * nint * CLK_PLL_1M;
+	}
+
+	return rate;
+}
+
+#define SPRD_PLL_WRITE_CHECK(pll, i, mask, val)		\
+	((sprd_pll_readl(pll, i) & mask) == val) ? 0 : -EFAULT
+
+static int _sprd_pll_set_rate(const struct sprd_pll *pll,
+			      unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct reg_cfg *cfg;
+	int ret = 0;
+	u32 mask, shift, width, ibias_val, index;
+	u32 reg_num = pll->regs[0], i = 0;
+	unsigned long kint, nint;
+	u64 refin, fvco = rate;
+
+	cfg = kcalloc(reg_num, sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	refin = pll_get_refin(pll);
+
+	mask = pmask(pll, PLL_PREDIV);
+	index = pindex(pll, PLL_PREDIV);
+	width = pwidth(pll, PLL_PREDIV);
+	if (width && (sprd_pll_readl(pll, index) & mask))
+		refin = refin * 2;
+
+	mask = pmask(pll, PLL_POSTDIV);
+	index = pindex(pll, PLL_POSTDIV);
+	width = pwidth(pll, PLL_POSTDIV);
+	cfg[index].msk = mask;
+	if (width && ((pll->fflag == 1 && fvco <= pll->fvco) ||
+		      (pll->fflag == 0 && fvco > pll->fvco)))
+		cfg[index].val |= mask;
+
+	if (width && fvco <= pll->fvco)
+		fvco = fvco * 2;
+
+	mask = pmask(pll, PLL_DIV_S);
+	index = pindex(pll, PLL_DIV_S);
+	cfg[index].val |= mask;
+	cfg[index].msk |= mask;
+
+	mask = pmask(pll, PLL_SDM_EN);
+	index = pindex(pll, PLL_SDM_EN);
+	cfg[index].val |= mask;
+	cfg[index].msk |= mask;
+
+	nint  = fvco/(refin * CLK_PLL_1M);
+
+	mask = pmask(pll, PLL_NINT);
+	index = pindex(pll, PLL_NINT);
+	shift = pshift(pll, PLL_NINT);
+	cfg[index].val |= (nint << shift) & mask;
+	cfg[index].msk |= mask;
+
+	mask = pmask(pll, PLL_KINT);
+	index = pindex(pll, PLL_KINT);
+	width = pwidth(pll, PLL_KINT);
+	shift = pshift(pll, PLL_KINT);
+	kint = DIV_ROUND_CLOSEST_ULL(((fvco - refin * nint * CLK_PLL_1M) /
+				      10000) * ((mask >> shift) + 1),
+				     refin * 100);
+	cfg[index].val |= (kint << shift) & mask;
+	cfg[index].msk |= mask;
+
+	ibias_val = pll_get_ibias(fvco, pll->itable);
+
+	mask = pmask(pll, PLL_IBIAS);
+	index = pindex(pll, PLL_IBIAS);
+	shift = pshift(pll, PLL_IBIAS);
+	cfg[index].val |= ibias_val << shift & mask;
+	cfg[index].msk |= mask;
+
+	for (i = 0; i < reg_num; i++) {
+		if (cfg[i].msk) {
+			sprd_pll_writel(pll, i, cfg[i].msk, cfg[i].val);
+			ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk,
+						   cfg[i].val);
+		}
+	}
+
+	if (!ret)
+		udelay(pll->udelay);
+
+	return ret;
+}
+
+static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct sprd_pll *pll = hw_to_sprd_pll(hw);
+
+	return _sprd_pll_recalc_rate(pll, parent_rate);
+}
+
+static int sprd_pll_set_rate(struct clk_hw *hw,
+			     unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct sprd_pll *pll = hw_to_sprd_pll(hw);
+
+	return _sprd_pll_set_rate(pll, rate, parent_rate);
+}
+
+static int sprd_pll_clk_prepare(struct clk_hw *hw)
+{
+	struct sprd_pll *pll = hw_to_sprd_pll(hw);
+
+	udelay(pll->udelay);
+
+	return 0;
+}
+
+static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	return rate;
+}
+
+const struct clk_ops sprd_pll_ops = {
+	.prepare = sprd_pll_clk_prepare,
+	.recalc_rate = sprd_pll_recalc_rate,
+	.round_rate = sprd_pll_round_rate,
+	.set_rate = sprd_pll_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_pll_ops);
diff --git a/drivers/clk/sprd/pll.h b/drivers/clk/sprd/pll.h
new file mode 100644
index 0000000..af5b2da
--- /dev/null
+++ b/drivers/clk/sprd/pll.h
@@ -0,0 +1,133 @@
+/*
+ * Spreadtrum clock pll configurations
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_PLL_H_
+#define _SPRD_PLL_H_
+
+#include "common.h"
+
+struct reg_cfg {
+	u32 val;
+	u32 msk;
+};
+
+struct clk_bit_field {
+	u8 shift;
+	u8 width;
+};
+
+enum {
+	PLL_LOCK_DONE,
+	PLL_DIV_S,
+	PLL_MOD_EN,
+	PLL_SDM_EN,
+	PLL_REFIN,
+	PLL_IBIAS,
+	PLL_N,
+	PLL_NINT,
+	PLL_KINT,
+	PLL_PREDIV,
+	PLL_POSTDIV,
+
+	PLL_FACT_MAX
+};
+
+/*
+ * struct sprd_pll - definition of adjustable pll clock
+ *
+ * @reg:	registers used to set the configuration of pll clock,
+ *		reg[0] shows how many registers this pll clock uses.
+ * @itable:	pll ibias table, itable[0] means how many items this
+ *		table includes
+ * @udelay	delay time after setting rate
+ * @factors	used to calculate the pll clock rate
+ * @fvco:	fvco threshold rate
+ * @fflag:	fvco flag
+ */
+struct sprd_pll {
+	const u32 *regs;
+	const u64 *itable;
+	const struct clk_bit_field *factors;
+	u16 udelay;
+	u16 k1;
+	u16 k2;
+	u16 fflag;
+	u64 fvco;
+
+	struct sprd_clk_common	common;
+};
+
+#define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg,	\
+				    _regs, _itable, _factors, _udelay,	\
+				    _k1, _k2, _fflag, _fvco)		\
+	struct sprd_pll _struct = {					\
+		.regs		= _regs,				\
+		.itable		= _itable,				\
+		.factors	= _factors,				\
+		.udelay		= _udelay,				\
+		.k1		= _k1,					\
+		.k2		= _k2,					\
+		.fflag		= _fflag,				\
+		.fvco		= _fvco,				\
+		.common		= {					\
+			.reg		= _reg,				\
+			.hw.init	= CLK_HW_INIT(_name,		\
+						      _parent,		\
+						      &sprd_pll_ops,	\
+						      0),		\
+		},							\
+	}
+
+#define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg,		\
+			       _regs, _itable, _factors,		\
+			       _udelay, _k1, _k2)			\
+	SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg,	\
+				    _regs, _itable, _factors,		\
+				    _udelay, _k1, _k2, 0, 0)
+
+#define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg,		\
+				_regs, _itable, _factors, _udelay)	\
+	SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg,	\
+				    _regs, _itable, _factors, _udelay,	\
+				    1000, 1000, 0, 0)
+
+static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw)
+{
+	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+	return container_of(common, struct sprd_pll, common);
+}
+
+static inline u32 sprd_pll_readl(const struct sprd_pll *pll, u8 index)
+{
+	const struct sprd_clk_common *common = &pll->common;
+
+	if (WARN_ON(index >= pll->regs[0]))
+		return 0;
+
+	return readl(common->base + pll->regs[index + 1]);
+}
+
+static inline void sprd_pll_writel(const struct sprd_pll *pll, u8 index,
+				  u32 msk, u32 val)
+{
+	const struct sprd_clk_common *common = &pll->common;
+	void __iomem *addr;
+	u32 reg;
+
+	if (WARN_ON(index >= pll->regs[0]))
+		return;
+
+	addr = common->base + pll->regs[index + 1];
+	reg = readl(addr);
+	writel((reg & ~msk) | val, addr);
+}
+
+extern const struct clk_ops sprd_pll_ops;
+
+#endif /* _SPRD_PLL_H_ */
-- 
2.7.4

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

* [PATCH V2 09/10] clk: sprd: add clocks support for SC9860
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (7 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 08/10] clk: sprd: add adjustable pll support Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  2017-07-11 10:56 ` [PATCH V2 10/10] arm64: dts: add clocks " Chunyan Zhang
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

This patch added the list of clocks for Spreadtrum's SC9860 SoC, together
with clock initialization code.

Original-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 drivers/clk/sprd/Kconfig                    |   10 +
 drivers/clk/sprd/Makefile                   |    3 +
 drivers/clk/sprd/sc9860-clk.c               | 1726 +++++++++++++++++++++++++++
 include/dt-bindings/clock/sprd,sc9860-clk.h |  375 ++++++
 4 files changed, 2114 insertions(+)
 create mode 100644 drivers/clk/sprd/sc9860-clk.c
 create mode 100644 include/dt-bindings/clock/sprd,sc9860-clk.h

diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
index 67a3287..8789247 100644
--- a/drivers/clk/sprd/Kconfig
+++ b/drivers/clk/sprd/Kconfig
@@ -2,3 +2,13 @@ config SPRD_COMMON_CLK
 	tristate "Clock support for Spreadtrum SoCs"
 	depends on ARCH_SPRD || COMPILE_TEST
 	default ARCH_SPRD
+
+if SPRD_COMMON_CLK
+
+# SoC Drivers
+
+config SPRD_SC9860_CLK
+	tristate "Support for the Spreadtrum SC9860 clocks"
+	depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST
+	default ARM64 && ARCH_SPRD
+endif
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index d693969..b0d81e5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -6,3 +6,6 @@ clk-sprd-y	+= mux.o
 clk-sprd-y	+= div.o
 clk-sprd-y	+= composite.o
 clk-sprd-y	+= pll.o
+
+## SoC support
+obj-$(CONFIG_SPRD_SC9860_CLK)	+= sc9860-clk.o
diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c
new file mode 100644
index 0000000..f70b941
--- /dev/null
+++ b/drivers/clk/sprd/sc9860-clk.c
@@ -0,0 +1,1726 @@
+/*
+ * Spreatrum SC9860 clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "common.h"
+#include "composite.h"
+#include "div.h"
+#include "gate.h"
+#include "mux.h"
+#include "pll.h"
+
+#include <dt-bindings/clock/sprd,sc9860-clk.h>
+
+static CLK_FIXED_RATE(ext_rco_100m, "ext-rco-100m", 0, 100000000, 0);
+static CLK_FIXED_RATE(ext_32k, "ext-32k", 0, 32768, 0);
+
+static CLK_FIXED_FACTOR(fac_4m,		"fac-4m",	"ext-26m",
+			6, 1, 0);
+static CLK_FIXED_FACTOR(fac_2m,		"fac-2m",	"ext-26m",
+			13, 1, 0);
+static CLK_FIXED_FACTOR(fac_1m,		"fac-1m",	"ext-26m",
+			26, 1, 0);
+static CLK_FIXED_FACTOR(fac_250k,	"fac-250k",	"ext-26m",
+			104, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll0_26m,	"rpll0-26m",	"ext-26m",
+			1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll1_26m,	"rpll1-26m",	"ext-26m",
+			1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_25m,	"rco-25m",	"ext-rc0-100m",
+			4, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_4m,	"rco-4m",	"ext-rc0-100m",
+			25, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_2m,	"rco-2m",	"ext-rc0-100m",
+			50, 1, 0);
+static CLK_FIXED_FACTOR(fac_3k2,	"fac-3k2",	"ext-32k",
+			10, 1, 0);
+static CLK_FIXED_FACTOR(fac_1k,		"fac-1k",	"ext-32k",
+			32, 1, 0);
+
+static SPRD_GATE_CLK(rpll0_gate,	"rpll0-gate",	"ext-26m", 0x402b016c,
+		     0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(rpll1_gate,	"rpll1-gate",	"ext-26m", 0x402b016c,
+		     0x1000, BIT(18), 0, 0);
+static SPRD_GATE_CLK(mpll0_gate,	"mpll0-gate",	"ext-26m", 0x402b00b0,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(mpll1_gate,	"mpll1-gate",	"ext-26m", 0x402b00b0,
+		     0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dpll0_gate,	"dpll0-gate",	"ext-26m", 0x402b00b4,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dpll1_gate,	"dpll1-gate",	"ext-26m", 0x402b00b4,
+		     0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gpll_gate,	"gpll-gate",	"ext-26m", 0x402b032c,
+		     0x1000, BIT(0), CLK_IGNORE_UNUSED,
+		     CLK_GATE_SET_TO_DISABLE);
+static SPRD_GATE_CLK(cppll_gate,	"cppll-gate",	"ext-26m", 0x402b02b4,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ltepll0_gate,	"ltepll0-gate",	"ext-26m", 0x402b00b8,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ltepll1_gate,	"ltepll1-gate",	"ext-26m", 0x402b010c,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(twpll_gate,	"twpll-gate",	"ext-26m", 0x402b00bc,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+
+/* GPLL/LPLL/DPLL/RPLL/CPLL */
+static const u64 const itable1[4] = {3, 780000000, 988000000, 1196000000};
+
+/* TWPLL/MPLL0/MPLL1 */
+static const u64 itable2[4] = {3, 1638000000, 2080000000, 2600000000UL};
+
+static const struct clk_bit_field const f_rpll[PLL_FACT_MAX] = {
+	{ .shift = 0,	.width = 1 },	/* lock_done	*/
+	{ .shift = 3,	.width = 1 },	/* div_s	*/
+	{ .shift = 80,	.width = 1 },	/* mod_en	*/
+	{ .shift = 81,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 14,	.width = 2 },	/* ibias	*/
+	{ .shift = 16,	.width = 7 },	/* n		*/
+	{ .shift = 4,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_rpll0[4] = { 3, 0x44, 0x48, 0x4c };
+static SPRD_PLL_WITH_ITABLE_1K(rpll0_clk, "rpll0", "rpll0-gate", 0x40400044,
+			       regs_rpll0, itable1, f_rpll, 200);
+
+static const u32 const regs_rpll1[4] = { 3, 0x50, 0x54, 0x58 };
+static SPRD_PLL_WITH_ITABLE_1K(rpll1_clk, "rpll1", "rpll1-gate", 0x40400050,
+			       regs_rpll1, itable1, f_rpll, 200);
+
+static const struct clk_bit_field const f_mpll0[PLL_FACT_MAX] = {
+	{ .shift = 20,	.width = 1 },	/* lock_done	*/
+	{ .shift = 19,	.width = 1 },	/* div_s	*/
+	{ .shift = 18,	.width = 1 },	/* mod_en	*/
+	{ .shift = 17,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 11,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 56,	.width = 1 },	/* postdiv	*/
+};
+static const u32 const regs_mpll0[3] = { 2, 0x24, 0x28 };
+static SPRD_PLL_WITH_ITABLE_K_FVCO(mpll0_clk, "mpll0", "mpll0-gate", 0x40400024,
+				   regs_mpll0, itable2, f_mpll0, 200,
+				   1000, 1000, 1, 1300000000);
+
+static const struct clk_bit_field const f_mpll1[PLL_FACT_MAX] = {
+	{ .shift = 20,	.width = 1 },	/* lock_done	*/
+	{ .shift = 19,	.width = 1 },	/* div_s	*/
+	{ .shift = 18,	.width = 1 },	/* mod_en	*/
+	{ .shift = 17,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 11,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 56,	.width = 1 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_mpll1[3] = { 2, 0x2c, 0x30 };
+static SPRD_PLL_WITH_ITABLE_1K(mpll1_clk, "mpll1", "mpll1-gate", 0x4040002c,
+			       regs_mpll1, itable2, f_mpll1, 200);
+
+static const struct clk_bit_field const f_dpll[PLL_FACT_MAX] = {
+	{ .shift = 16,	.width = 1 },	/* lock_done	*/
+	{ .shift = 15,	.width = 1 },	/* div_s	*/
+	{ .shift = 14,	.width = 1 },	/* mod_en	*/
+	{ .shift = 13,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 8,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_dpll0[3] = { 2, 0x34, 0x38 };
+static SPRD_PLL_WITH_ITABLE_1K(dpll0_clk, "dpll0", "dpll0-gate", 0x40400034,
+			       regs_dpll0, itable1, f_dpll, 200);
+
+static const u32 const regs_dpll1[3] = { 2, 0x3c, 0x40 };
+static SPRD_PLL_WITH_ITABLE_1K(dpll1_clk, "dpll1", "dpll1-gate", 0x4040003c,
+			       regs_dpll1, itable1, f_dpll, 200);
+
+static const struct clk_bit_field const f_gpll[PLL_FACT_MAX] = {
+	{ .shift = 18,	.width = 1 },	/* lock_done	*/
+	{ .shift = 15,	.width = 1 },	/* div_s	*/
+	{ .shift = 14,	.width = 1 },	/* mod_en	*/
+	{ .shift = 13,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 8,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 17,	.width = 1 },	/* postdiv	*/
+};
+static const u32 const regs_gpll[3] = { 2, 0x9c, 0xa0 };
+static SPRD_PLL_WITH_ITABLE_K_FVCO(gpll_clk, "gpll", "gpll-gate", 0x4040009c,
+				   regs_gpll, itable1, f_gpll, 200,
+				   1000, 1000, 1, 600000000);
+
+static const struct clk_bit_field const f_cppll[PLL_FACT_MAX] = {
+	{ .shift = 17,	.width = 1 },	/* lock_done	*/
+	{ .shift = 15,	.width = 1 },	/* div_s	*/
+	{ .shift = 14,	.width = 1 },	/* mod_en	*/
+	{ .shift = 13,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 8,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_cppll[3] = { 2, 0xc4, 0xc8 };
+static SPRD_PLL_WITH_ITABLE_1K(cppll_clk, "cppll", "cppll-gate", 0x404000c4,
+			       regs_cppll, itable1, f_cppll, 200);
+
+static const struct clk_bit_field const f_ltepll[PLL_FACT_MAX] = {
+	{ .shift = 31,	.width = 1 },	/* lock_done	*/
+	{ .shift = 27,	.width = 1 },	/* div_s	*/
+	{ .shift = 26,	.width = 1 },	/* mod_en	*/
+	{ .shift = 25,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 20,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_ltepll0[3] = { 2, 0x64, 0x68 };
+static SPRD_PLL_WITH_ITABLE_1K(ltepll0_clk, "ltepll0", "ltepll0-gate",
+			       0x40400064, regs_ltepll0, itable1,
+			       f_ltepll, 200);
+static const u32 const regs_ltepll1[3] = { 2, 0x6c, 0x70 };
+static SPRD_PLL_WITH_ITABLE_1K(ltepll1_clk, "ltepll1", "ltepll1-gate",
+			       0x4040006c, regs_ltepll1, itable1,
+			       f_ltepll, 200);
+
+static const struct clk_bit_field const f_twpll[PLL_FACT_MAX] = {
+	{ .shift = 21,	.width = 1 },	/* lock_done	*/
+	{ .shift = 20,	.width = 1 },	/* div_s	*/
+	{ .shift = 19,	.width = 1 },	/* mod_en	*/
+	{ .shift = 18,	.width = 1 },	/* sdm_en	*/
+	{ .shift = 0,	.width = 0 },	/* refin	*/
+	{ .shift = 13,	.width = 2 },	/* ibias	*/
+	{ .shift = 0,	.width = 7 },	/* n		*/
+	{ .shift = 57,	.width = 7 },	/* nint		*/
+	{ .shift = 32,	.width = 23},	/* kint		*/
+	{ .shift = 0,	.width = 0 },	/* prediv	*/
+	{ .shift = 0,	.width = 0 },	/* postdiv	*/
+};
+static const u32 const regs_twpll[3] = { 2, 0x5c, 0x60 };
+static SPRD_PLL_WITH_ITABLE_1K(twpll_clk, "twpll", "twpll-gate", 0x4040005c,
+			       regs_twpll, itable2, f_twpll, 200);
+
+static CLK_FIXED_FACTOR(gpll_42m5, "gpll-42m5", "gpll", 20, 1, 0);
+static CLK_FIXED_FACTOR(twpll_768m, "twpll-768m", "twpll", 2, 1, 0);
+static CLK_FIXED_FACTOR(twpll_384m, "twpll-384m", "twpll", 4, 1, 0);
+static CLK_FIXED_FACTOR(twpll_192m, "twpll-192m", "twpll", 8, 1, 0);
+static CLK_FIXED_FACTOR(twpll_96m, "twpll-96m", "twpll", 16, 1, 0);
+static CLK_FIXED_FACTOR(twpll_48m, "twpll-48m", "twpll", 32, 1, 0);
+static CLK_FIXED_FACTOR(twpll_24m, "twpll-24m", "twpll", 64, 1, 0);
+static CLK_FIXED_FACTOR(twpll_12m, "twpll-12m", "twpll", 128, 1, 0);
+static CLK_FIXED_FACTOR(twpll_512m, "twpll-512m", "twpll", 3, 1, 0);
+static CLK_FIXED_FACTOR(twpll_256m, "twpll-256m", "twpll", 6, 1, 0);
+static CLK_FIXED_FACTOR(twpll_128m, "twpll-128m", "twpll", 12, 1, 0);
+static CLK_FIXED_FACTOR(twpll_64m, "twpll-64m", "twpll", 24, 1, 0);
+static CLK_FIXED_FACTOR(twpll_307m2, "twpll-307m2", "twpll", 5, 1, 0);
+static CLK_FIXED_FACTOR(twpll_153m6, "twpll-153m6", "twpll", 10, 1, 0);
+static CLK_FIXED_FACTOR(twpll_76m8, "twpll-76m8", "twpll", 20, 1, 0);
+static CLK_FIXED_FACTOR(twpll_51m2, "twpll-51m2", "twpll", 30, 1, 0);
+static CLK_FIXED_FACTOR(twpll_38m4, "twpll-38m4", "twpll", 40, 1, 0);
+static CLK_FIXED_FACTOR(twpll_19m2, "twpll-19m2", "twpll", 80, 1, 0);
+static CLK_FIXED_FACTOR(l0_614m4, "l0-614m4", "ltepll0", 2, 1, 0);
+static CLK_FIXED_FACTOR(l0_409m6, "l0-409m6", "ltepll0", 3, 1, 0);
+static CLK_FIXED_FACTOR(l0_38m, "l0-38m", "ltepll0", 32, 1, 0);
+static CLK_FIXED_FACTOR(l1_38m, "l1-38m", "ltepll1", 32, 1, 0);
+static CLK_FIXED_FACTOR(rpll0_192m, "rpll0-192m", "rpll0", 6, 1, 0);
+static CLK_FIXED_FACTOR(rpll0_96m, "rpll0-96m", "rpll0", 12, 1, 0);
+static CLK_FIXED_FACTOR(rpll0_48m, "rpll0-48m", "rpll0", 24, 1, 0);
+static CLK_FIXED_FACTOR(rpll1_468m, "rpll1-468m", "rpll1", 2, 1, 0);
+static CLK_FIXED_FACTOR(rpll1_192m, "rpll1-192m", "rpll1", 6, 1, 0);
+static CLK_FIXED_FACTOR(rpll1_96m, "rpll1-96m", "rpll1", 12, 1, 0);
+static CLK_FIXED_FACTOR(rpll1_64m, "rpll1-64m", "rpll1", 18, 1, 0);
+static CLK_FIXED_FACTOR(rpll1_48m, "rpll1-48m", "rpll1", 24, 1, 0);
+static CLK_FIXED_FACTOR(dpll0_50m, "dpll0-50m", "dpll0", 16, 1, 0);
+static CLK_FIXED_FACTOR(dpll1_50m, "dpll1-50m", "dpll1", 16, 1, 0);
+static CLK_FIXED_FACTOR(cppll_50m, "cppll-50m", "cppll", 18, 1, 0);
+static CLK_FIXED_FACTOR(m0_39m, "m0-39m", "mpll0", 32, 1, 0);
+static CLK_FIXED_FACTOR(m1_63m, "m1-63m", "mpll1", 32, 1, 0);
+
+static const char * const aon_apb_parents[] = { "rco-25m",	"ext-26m",
+						"ext-rco-100m",	"twpll-96m",
+						"twpll-128m",
+						"twpll-153m6" };
+static SPRD_COMP_CLK(aon_apb, "aon-apb", aon_apb_parents, 0x402d0230,
+		     0,	0, 3, 8, 2, 0);
+
+static const char * const aux_parents[] = { "ext-32k",		"rpll0-26m",
+					    "rpll1-26m",	"ext-26m",
+					    "cppll-50m",	"rco-25m",
+					    "dpll0-50m",	"dpll1-50m",
+					    "gpll-42m5",	"twpll-48m",
+					    "m0-39m",		"m1-63m",
+					    "l0-38m",		"l1-38m" };
+
+static SPRD_COMP_CLK(aux0_clk,	"aux0",		aux_parents, 0x402d0238,
+		     0, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK(aux1_clk,	"aux1",		aux_parents, 0x402d023c,
+		     0, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK(aux2_clk,	"aux2",		aux_parents, 0x402d0240,
+		     0, 0, 5, 8, 4, 0);
+static SPRD_COMP_CLK(probe_clk,	"probe",	aux_parents, 0x402d0244,
+		     0, 0, 5, 8, 4, 0);
+
+static const char * const sp_ahb_parents[] = {	"rco-4m",	"ext-26m",
+						"ext-rco-100m",	"twpll-96m",
+						"twpll-128m",
+						"twpll-153m6" };
+static SPRD_COMP_CLK(sp_ahb,	"sp-ahb",	sp_ahb_parents, 0x402d02d0,
+		     0, 0, 3, 8, 2, 0);
+
+static const char * const cci_parents[] = {	"ext-26m",	"twpll-384m",
+						"l0-614m4",	"twpll-768m" };
+static SPRD_COMP_CLK(cci_clk,	"cci",		cci_parents, 0x402d0304,
+		     0,	0, 2, 8, 2, 0);
+static SPRD_COMP_CLK(gic_clk,	"gic",		cci_parents, 0x402d0304,
+		     0, 0, 2, 8, 2, 0);
+static SPRD_COMP_CLK(cssys_clk,	"cssys",	cci_parents, 0x402d0310,
+		     0, 0, 2, 8, 2, 0);
+
+static const char * const sdio_2x_parents[] = {	"fac-1m",	"ext-26m",
+						"twpll-307m2",	"twpll-384m",
+						"l0-409m6" };
+static SPRD_COMP_CLK(sdio0_2x,	"sdio0-2x",	sdio_2x_parents, 0x402d0328,
+		     0, 0, 3, 8, 4, 0);
+static SPRD_COMP_CLK(sdio1_2x,	"sdio1-2x",	sdio_2x_parents, 0x402d0330,
+		     0, 0, 3, 8, 4, 0);
+static SPRD_COMP_CLK(sdio2_2x,	"sdio2-2x",	sdio_2x_parents, 0x402d0338,
+		     0, 0, 3, 8, 4, 0);
+static SPRD_COMP_CLK(emmc_2x,	"emmc-2x",	sdio_2x_parents, 0x402d0340,
+		     0, 0, 3, 8, 4, 0);
+
+static const char * const uart_parents[] = {	"ext-26m",	"twpll-48m",
+						"twpll-51m2",	"twpll-96m" };
+static SPRD_COMP_CLK(uart0_clk,	"uart0",	uart_parents, 0x20000030,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(uart1_clk,	"uart1",	uart_parents, 0x20000034,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(uart2_clk,	"uart2",	uart_parents, 0x20000038,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(uart3_clk,	"uart3",	uart_parents, 0x2000003c,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(uart4_clk,	"uart4",	uart_parents, 0x20000040,
+		     0, 0, 2, 8, 3, 0);
+
+static const char * const i2c_parents[] = { "ext-26m", "twpll-48m",
+					    "twpll-51m2", "twpll-153m6" };
+static SPRD_COMP_CLK(i2c0_clk,	"i2c0", i2c_parents, 0x20000044,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(i2c1_clk,	"i2c1", i2c_parents, 0x20000048,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(i2c2_clk,	"i2c2", i2c_parents, 0x2000004c,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(i2c3_clk,	"i2c3", i2c_parents, 0x20000050,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(i2c4_clk,	"i2c4", i2c_parents, 0x20000054,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(i2c5_clk,	"i2c5", i2c_parents, 0x20000058,
+		     0, 0, 2, 8, 3, 0);
+
+static const char * const spi_parents[] = {	"ext-26m",	"twpll-128m",
+						"twpll-153m6",	"twpll-192m" };
+static SPRD_COMP_CLK(spi0_clk,	"spi0",	spi_parents, 0x2000005c,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(spi1_clk,	"spi1",	spi_parents, 0x20000060,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(spi2_clk,	"spi2",	spi_parents, 0x20000064,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(spi3_clk,	"spi3",	spi_parents, 0x20000068,
+		     0, 0, 2, 8, 3, 0);
+
+static const char * const iis_parents[] = { "ext-26m",
+					    "twpll-128m",
+					    "twpll-153m6" };
+static SPRD_COMP_CLK(iis0_clk,	"iis0",	iis_parents, 0x2000006c,
+		     0, 0, 2, 8, 6, 0);
+static SPRD_COMP_CLK(iis1_clk,	"iis1",	iis_parents, 0x20000070,
+		     0, 0, 2, 8, 6, 0);
+static SPRD_COMP_CLK(iis2_clk,	"iis2",	iis_parents, 0x20000074,
+		     0, 0, 2, 8, 6, 0);
+static SPRD_COMP_CLK(iis3_clk,	"iis3",	iis_parents, 0x20000078,
+		     0, 0, 2, 8, 6, 0);
+
+static const u8 mcu_table[] = { 0, 1, 2, 3, 4, 8 };
+static const char * const lit_mcu_parents[] = {	"ext-26m",	"twpll-512m",
+						"twpll-768m",	"ltepll0",
+						"twpll",	"mpll0" };
+static SPRD_COMP_CLK(lit_mcu,	"lit-mcu",	lit_mcu_parents, 0x40880020,
+		     mcu_table, 0, 4, 4, 3, 0);
+
+static const char * const big_mcu_parents[] = {	"ext-26m",	"twpll-512m",
+						"twpll-768m",	"ltepll0",
+						"twpll",	"mpll1" };
+static SPRD_COMP_CLK(big_mcu,	"big-mcu",	big_mcu_parents, 0x40880024,
+		     mcu_table, 0, 4, 4, 3, 0);
+
+static const char * const gpu_parents[] = { "twpll-512m",
+					    "twpll-768m",
+					    "gpll" };
+static SPRD_COMP_CLK(gpu_clk,	"gpu",	gpu_parents, 0x60200020,
+		     0, 0, 2, 8, 4, 0);
+
+static const char * const vsp_parents[] = {	"twpll-76m8",	"twpll-128m",
+						"twpll-256m",	"twpll-307m2",
+						"twpll-384m" };
+static SPRD_COMP_CLK(vsp_clk,	"vsp",	vsp_parents, 0x61000024,
+		     0, 0, 3, 8, 2, 0);
+
+static const char * const dispc_parents[] = {	"twpll-76m8",	"twpll-128m",
+						"twpll-256m",	"twpll-307m2" };
+static SPRD_COMP_CLK(vsp_enc, "vsp-enc", dispc_parents, 0x61000028,
+		     0, 0, 2, 8, 2, 0);
+static SPRD_COMP_CLK(dispc0_dpi, "dispc0-dpi", dispc_parents, 0x63000034,
+		     0, 0, 2, 8, 2, 0);
+static SPRD_COMP_CLK(dispc1_dpi, "dispc1-dpi", dispc_parents, 0x63000040,
+		     0, 0, 2, 8, 2, 0);
+
+static const char * const sensor_parents[] = {	"ext-26m",	"twpll-48m",
+						"twpll-76m8",	"twpll-96m" };
+static SPRD_COMP_CLK(sensor0_clk, "sensor0", sensor_parents, 0x62000024,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(sensor1_clk, "sensor1", sensor_parents, 0x62000028,
+		     0, 0, 2, 8, 3, 0);
+static SPRD_COMP_CLK(sensor2_clk, "sensor2", sensor_parents, 0x6200002c,
+		     0, 0, 2, 8, 3, 0);
+
+static SPRD_DIV_CLK(sdio0_1x,	"sdio0-1x",	"sdio0-2x",	0x402d032c,
+		    8, 1, 0);
+static SPRD_DIV_CLK(sdio1_1x,	"sdio1-1x",	"sdio1-2x",	0x402d0334,
+		    8, 1, 0);
+static SPRD_DIV_CLK(sdio2_1x,	"sdio2-1x",	"sdio2-2x",	0x402d033c,
+		    8, 1, 0);
+static SPRD_DIV_CLK(emmc_1x,	"emmc-1x",	"emmc-2x",	0x402d0344,
+		    8, 1, 0);
+
+#define SC9860_MUX_FLAG	\
+	(CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT)
+
+static const char * const adi_parents[] = {	"rco-4m",	"ext-26m",
+						"rco-25m",	"twpll-38m4",
+						"twpll-51m2" };
+static SPRD_MUX_CLK(adi_clk,	"adi",	adi_parents, NULL, 0x402d0234,
+		    0, 3, SC9860_MUX_FLAG);
+
+static const char * const pwm_parents[] = {	"ext-32k",	"ext-26m",
+						"rco-4m",	"rco-25m",
+						"twpll-48m" };
+static SPRD_MUX_CLK(pwm0_clk,	"pwm0",	pwm_parents, NULL, 0x402d0248,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(pwm1_clk,	"pwm1",	pwm_parents, NULL, 0x402d024c,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(pwm2_clk,	"pwm2",	pwm_parents, NULL, 0x402d0250,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(pwm3_clk,	"pwm3",	pwm_parents, NULL, 0x402d0254,
+		    0, 3, SC9860_MUX_FLAG);
+
+static const char * const efuse_parents[] = { "rco-25m", "ext-26m" };
+static SPRD_MUX_CLK(efuse_clk, "efuse", efuse_parents, NULL, 0x402d0258,
+		    0, 1, SC9860_MUX_FLAG);
+
+static const char * const cm3_uart_parents[] = { "rco-4m",	"ext-26m",
+						 "rco-100m",	"twpll-48m",
+						 "twpll-51m2",	"twpll-96m",
+						 "twpll-128m" };
+static SPRD_MUX_CLK(cm3_uart0, "cm3-uart0", cm3_uart_parents, NULL, 0x402d025c,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(cm3_uart1, "cm3-uart1", cm3_uart_parents, NULL, 0x402d0260,
+		    0, 3, SC9860_MUX_FLAG);
+
+static const char * const thm_parents[] = { "ext-32k", "fac-250k" };
+static SPRD_MUX_CLK(thm_clk,	"thm",	thm_parents, NULL, 0x402d0270,
+		    0, 1, SC9860_MUX_FLAG);
+
+static const char * const cm3_i2c_parents[] = {	"rco-4m",
+						"ext-26m",
+						"rco-100m",
+						"twpll-48m",
+						"twpll-51m2",
+						"twpll-153m6" };
+static SPRD_MUX_CLK(cm3_i2c0, "cm3-i2c0", cm3_i2c_parents, NULL, 0x402d0274,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(cm3_i2c1, "cm3-i2c1", cm3_i2c_parents, NULL, 0x402d0278,
+		    0, 3, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(aon_i2c, "aon-i2c",	cm3_i2c_parents, NULL, 0x402d0280,
+		    0, 3, SC9860_MUX_FLAG);
+
+static const char * const cm4_spi_parents[] = {	"ext-26m",	"twpll-96m",
+						"rco-100m",	"twpll-128m",
+						"twpll-153m6",	"twpll-192m" };
+static SPRD_MUX_CLK(cm4_spi, "cm4-spi", cm4_spi_parents, NULL, 0x402d027c,
+		    0, 3, SC9860_MUX_FLAG);
+
+static SPRD_MUX_CLK(avs_clk, "avs", uart_parents, NULL, 0x402d0284,
+		    0, 2, SC9860_MUX_FLAG);
+
+static const char * const ca53_dap_parents[] = { "ext-26m",	"rco-4m",
+						 "rco-100m",	"twpll-76m8",
+						 "twpll-128m",	"twpll-153m6" };
+static SPRD_MUX_CLK(ca53_dap, "ca53-dap", ca53_dap_parents, NULL, 0x402d0288,
+		    0, 3, SC9860_MUX_FLAG);
+
+static const char * const ca53_ts_parents[] = {	"ext-32k", "ext-26m",
+						"clk-twpll-128m",
+						"clk-twpll-153m6" };
+static SPRD_MUX_CLK(ca53_ts, "ca53-ts", ca53_ts_parents, NULL, 0x402d0290,
+		    0, 2, SC9860_MUX_FLAG);
+
+static const char * const djtag_tck_parents[] = { "rco-4m", "ext-26m" };
+static SPRD_MUX_CLK(djtag_tck, "djtag-tck", djtag_tck_parents, NULL,
+	0x402d02c8, 0, 1, SC9860_MUX_FLAG);
+
+static const char * const pmu_parents[] = { "ext-32k", "rco-4m", "clk-4m" };
+static SPRD_MUX_CLK(pmu_clk, "pmu", pmu_parents, NULL, 0x402d02e0,
+		    0, 2, SC9860_MUX_FLAG);
+
+static const char * const pmu_26m_parents[] = { "rco-25m", "ext-26m" };
+static SPRD_MUX_CLK(pmu_26m, "pmu-26m", pmu_26m_parents, NULL,
+		    0x402d02e4, 0, 1, SC9860_MUX_FLAG);
+
+static const char * const debounce_parents[] = { "ext-32k", "rco-4m",
+						 "rco-25m", "ext-26m" };
+static SPRD_MUX_CLK(debounce_clk, "debounce", debounce_parents, NULL,
+		    0x402d02e8, 0, 2, SC9860_MUX_FLAG);
+
+static const char * const otg2_ref_parents[] = { "twpll-12m", "twpll-24m" };
+static SPRD_MUX_CLK(otg2_ref, "otg2-ref", otg2_ref_parents, NULL,
+		    0x402d02f4, 0, 1, SC9860_MUX_FLAG);
+
+static const char * const usb3_ref_parents[] = { "twpll-24m", "twpll-19m2",
+						 "twpll-48m" };
+static SPRD_MUX_CLK(usb3_ref, "usb3-ref", usb3_ref_parents, NULL,
+		    0x402d02f8, 0, 2, SC9860_MUX_FLAG);
+
+static const char * const ap_axi_parents[] = { "ext-26m", "twpll-76m8",
+					       "twpll-128m", "twpll-256m" };
+static SPRD_MUX_CLK(ap_axi, "ap-axi", ap_axi_parents, NULL,
+		    0x402d0324, 0, 2, SC9860_MUX_FLAG);
+
+static const char * const ap_apb_parents[] = { "ext-26m", "twpll-64m",
+					       "twpll-96m", "twpll-128m" };
+static SPRD_MUX_CLK(ap_apb, "ap-apb", ap_apb_parents, NULL,
+		    0x20000020, 0, 1, SC9860_MUX_FLAG);
+
+static const char * const ahb_parents[] = { "ext-26m", "twpll-96m",
+					    "twpll-128m", "twpll-153m6" };
+static SPRD_MUX_CLK(ahb_vsp, "ahb-vsp", ahb_parents, NULL,
+		    0x61000020, 0, 2, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(ahb_disp, "ahb-disp", ahb_parents, NULL,
+		    0x63000020, 0, 2, SC9860_MUX_FLAG);
+static SPRD_MUX_CLK(ahb_cam, "ahb-cam", ahb_parents, NULL,
+		    0x62000020, 0, 2, SC9860_MUX_FLAG);
+
+static SPRD_GATE_CLK(mipi_csi0_eb, "mipi-csi0-eb", "ahb-cam", 0x6200004c,
+		     0, BIT(16), 0, 0);
+static SPRD_GATE_CLK(mipi_csi1_eb, "mipi-csi1-eb", "ahb-cam", 0x62000050,
+		     0, BIT(16), 0, 0);
+static SPRD_GATE_CLK(usb3_eb,		"usb3-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(usb3_suspend,	"usb3-suspend", "ap-axi", 0x20210000,
+		     0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(usb3_ref_eb,	"usb3-ref-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dma_eb,		"dma-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(sdio0_eb,		"sdio0-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(sdio1_eb,		"sdio1-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(sdio2_eb,		"sdio2-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(emmc_eb,		"emmc-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(rom_eb,		"rom-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(busmon_eb,		"busmon-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(cc63s_eb,		"cc63s-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(22), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(cc63p_eb,		"cc63p-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(23), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ce0_eb,		"ce0-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(24), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ce1_eb,		"ce1-eb",	"ap-axi", 0x20210000,
+		     0x1000, BIT(25), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(avs_lit_eb,	"avs-lit-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(avs_big_eb,	"avs-big-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc5_eb,	"ap-intc5-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gpio_eb,		"gpio-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pwm0_eb,		"pwm0-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pwm1_eb,		"pwm1-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pwm2_eb,		"pwm2-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pwm3_eb,		"pwm3-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(kpd_eb,		"kpd-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aon_sys_eb,	"aon-sys-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_sys_eb,		"ap-sys-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aon_tmr_eb,	"aon-tmr-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_tmr0_eb,	"ap-tmr0-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(efuse_eb,		"efuse-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(eic_eb,		"eic-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pub1_reg_eb,	"pub1-reg-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(adi_eb,		"adi-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc0_eb,	"ap-intc0-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc1_eb,	"ap-intc1-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc2_eb,	"ap-intc2-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(19), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc3_eb,	"ap-intc3-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_intc4_eb,	"ap-intc4-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(21), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(splk_eb,		"splk-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(22), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(mspi_eb,		"mspi-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(23), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pub0_reg_eb,	"pub0-reg-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(24), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pin_eb,		"pin-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(25), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aon_ckg_eb,	"aon-ckg-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(26), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gpu_eb,		"gpu-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(27), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(apcpu_ts0_eb,	"apcpu-ts0-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(28), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(apcpu_ts1_eb,	"apcpu-ts1-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(29), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dap_eb,		"dap-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(30), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c_eb,		"i2c-eb",	"aon-apb", 0x402e0000,
+		     0x1000, BIT(31), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(pmu_eb,		"pmu-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(thm_eb,		"thm-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aux0_eb,		"aux0-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aux1_eb,		"aux1-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aux2_eb,		"aux2-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(probe_eb,		"probe-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gpu0_avs_eb,	"gpu0-avs-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gpu1_avs_eb,	"gpu1-avs-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(apcpu_wdg_eb,	"apcpu-wdg-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_tmr1_eb,	"ap-tmr1-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_tmr2_eb,	"ap-tmr2-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(disp_emc_eb,	"disp-emc-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(zip_emc_eb,	"zip-emc-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(gsp_emc_eb,	"gsp-emc-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(osc_aon_eb,	"osc-aon-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(lvds_trx_eb,	"lvds-trx-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(lvds_tcxo_eb,	"lvds-tcxo-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(mdar_eb,		"mdar-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(rtc4m0_cal_eb, "rtc4m0-cal-eb", "aon-apb", 0x402e0004,
+		     0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(rct100m_cal_eb, "rct100m-cal-eb", "aon-apb", 0x402e0004,
+		     0x1000, BIT(19), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(djtag_eb,		"djtag-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(mbox_eb,		"mbox-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(21), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aon_dma_eb,	"aon-dma-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(22), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dbg_emc_eb,	"dbg-emc-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(23), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(lvds_pll_div_en, "lvds-pll-div-en", "aon-apb", 0x402e0004,
+		     0x1000, BIT(24), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(def_eb,		"def-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(25), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(aon_apb_rsv0,	"aon-apb-rsv0",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(26), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(orp_jtag_eb,	"orp-jtag-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(27), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(vsp_eb,		"vsp-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(28), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(cam_eb,		"cam-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(29), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(disp_eb,		"disp-eb",	"aon-apb", 0x402e0004,
+		     0x1000, BIT(30), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(dbg_axi_if_eb,	"dbg-axi-if-eb", "aon-apb", 0x402e0004,
+		     0x1000, BIT(31), CLK_IGNORE_UNUSED, 0);
+
+static SPRD_GATE_CLK(sdio0_2x_en,	"sdio0-2x-en",	"aon-apb", 0x402e013c,
+			       0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(sdio1_2x_en,	"sdio1-2x-en",	"aon-apb", 0x402e013c,
+			       0x1000, BIT(4), 0, 0);
+static SPRD_GATE_CLK(sdio2_2x_en,	"sdio2-2x-en",	"aon-apb", 0x402e013c,
+			       0x1000, BIT(6), 0, 0);
+static SPRD_GATE_CLK(emmc_2x_en,	"emmc-2x-en",	"aon-apb", 0x402e013c,
+			       0x1000, BIT(9), 0, 0);
+
+static SPRD_GATE_CLK(agcp_iis0_eb,	"agcp-iis0-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(0), 0, 0);
+static SPRD_GATE_CLK(agcp_iis1_eb,	"agcp-iis1-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(1), 0, 0);
+static SPRD_GATE_CLK(agcp_iis2_eb,	"agcp-iis2-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(2), 0, 0);
+static SPRD_GATE_CLK(agcp_iis3_eb,	"agcp-iis3-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(3), 0, 0);
+static SPRD_GATE_CLK(agcp_uart_eb,	"agcp-uart-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(4), 0, 0);
+static SPRD_GATE_CLK(agcp_dmacp_eb,	"agcp-dmacp-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(5), 0, 0);
+static SPRD_GATE_CLK(agcp_dmaap_eb,	"agcp-dmaap-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(6), 0, 0);
+static SPRD_GATE_CLK(agcp_arc48k_eb,	"agcp-arc48k-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(10), 0, 0);
+static SPRD_GATE_CLK(agcp_src44p1k_eb,	"agcp-src44p1k-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(11), 0, 0);
+static SPRD_GATE_CLK(agcp_mcdt_eb,	"agcp-mcdt-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(12), 0, 0);
+static SPRD_GATE_CLK(agcp_vbcifd_eb,	"agcp-vbcifd-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(13), 0, 0);
+static SPRD_GATE_CLK(agcp_vbc_eb,	"agcp-vbc-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(14), 0, 0);
+static SPRD_GATE_CLK(agcp_spinlock_eb,	"agcp-spinlock-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(15), 0, 0);
+static SPRD_GATE_CLK(agcp_icu_eb,	"agcp-icu-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(agcp_ap_ashb_eb,	"agcp-ap-ashb-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(17), 0, 0);
+static SPRD_GATE_CLK(agcp_cp_ashb_eb,	"agcp-cp-ashb-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(18), 0, 0);
+static SPRD_GATE_CLK(agcp_aud_eb,	"agcp-aud-eb",		"aon-apb",
+		     0x415e0000, 0x100, BIT(19), 0, 0);
+static SPRD_GATE_CLK(agcp_audif_eb,	"agcp-audif-eb",	"aon-apb",
+		     0x415e0000, 0x100, BIT(20), 0, 0);
+
+static SPRD_GATE_CLK(vsp_dec_eb,	"vsp-dec-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(0), 0, 0);
+static SPRD_GATE_CLK(vsp_ckg_eb,	"vsp-ckg-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(1), 0, 0);
+static SPRD_GATE_CLK(vsp_mmu_eb,	"vsp-mmu-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(vsp_enc_eb,	"vsp-enc-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(3), 0, 0);
+static SPRD_GATE_CLK(vpp_eb,		"vpp-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(4), 0, 0);
+static SPRD_GATE_CLK(vsp_26m_eb,	"vsp-26m-eb",	"ahb_vsp", 0x61100000,
+		     0x1000, BIT(5), 0, 0);
+
+static SPRD_GATE_CLK(vsp_axi_gate,	"vsp-axi-gate",	"ahb_vsp", 0x61100008,
+		     0, BIT(0), 0, 0);
+static SPRD_GATE_CLK(vsp_enc_gate,	"vsp-enc-gate",	"ahb_vsp", 0x61100008,
+		     0, BIT(1), 0, 0);
+static SPRD_GATE_CLK(vpp_axi_gate,	"vpp-axi-gate",	"ahb_vsp", 0x61100008,
+		     0, BIT(2), 0, 0);
+static SPRD_GATE_CLK(vsp_bm_gate,	"vsp-bm-gate",	"ahb_vsp", 0x61100008,
+		     0, BIT(8), 0, 0);
+static SPRD_GATE_CLK(vsp_enc_bm_gate, "vsp-enc-bm-gate", "ahb_vsp", 0x61100008,
+		     0, BIT(9), 0, 0);
+static SPRD_GATE_CLK(vpp_bm_gate, "vpp-bm-gate", "ahb_vsp", 0x61100008,
+		     0, BIT(10), 0, 0);
+static SPRD_GATE_CLK(dcam0_eb,		"dcam0-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(0), 0, 0);
+static SPRD_GATE_CLK(dcam1_eb,		"dcam1-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(1), 0, 0);
+static SPRD_GATE_CLK(isp0_eb,		"isp0-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(csi0_eb,		"csi0-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(3), 0, 0);
+static SPRD_GATE_CLK(csi1_eb,		"csi1-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(4), 0, 0);
+static SPRD_GATE_CLK(jpg0_eb,		"jpg0-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(5), 0, 0);
+static SPRD_GATE_CLK(jpg1_eb,		"jpg1-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(6), 0, 0);
+static SPRD_GATE_CLK(cam_ckg_eb,	"cam-ckg-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(7), 0, 0);
+static SPRD_GATE_CLK(cam_mmu_eb,	"cam-mmu-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(8), 0, 0);
+static SPRD_GATE_CLK(isp1_eb,		"isp1-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(9), 0, 0);
+static SPRD_GATE_CLK(cpp_eb,		"cpp-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(10), 0, 0);
+static SPRD_GATE_CLK(mmu_pf_eb,		"mmu-pf-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(11), 0, 0);
+static SPRD_GATE_CLK(isp2_eb,		"isp2-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(12), 0, 0);
+static SPRD_GATE_CLK(dcam2isp_if_eb, "dcam2isp-if-eb", "ahb_cam", 0x62100000,
+		     0x1000, BIT(13), 0, 0);
+static SPRD_GATE_CLK(isp2dcam_if_eb, "isp2dcam-if-eb", "ahb_cam", 0x62100000,
+		     0x1000, BIT(14), 0, 0);
+static SPRD_GATE_CLK(isp_lclk_eb,	"isp-lclk-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(15), 0, 0);
+static SPRD_GATE_CLK(isp_iclk_eb,	"isp-iclk-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(16), 0, 0);
+static SPRD_GATE_CLK(isp_mclk_eb,	"isp-mclk-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(17), 0, 0);
+static SPRD_GATE_CLK(isp_pclk_eb,	"isp-pclk-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(18), 0, 0);
+static SPRD_GATE_CLK(isp_isp2dcam_eb, "isp-isp2dcam-eb", "ahb_cam", 0x62100000,
+		     0x1000, BIT(19), 0, 0);
+static SPRD_GATE_CLK(dcam0_if_eb,	"dcam0-if-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(20), 0, 0);
+static SPRD_GATE_CLK(clk26m_if_eb,	"clk26m-if-eb",	"ahb-cam", 0x62100000,
+		     0x1000, BIT(21), 0, 0);
+
+static SPRD_GATE_CLK(cphy0_gate, "cphy0-gate", "ahb-cam", 0x62100008,
+		     0, BIT(0), 0, 0);
+static SPRD_GATE_CLK(mipi_csi0_gate, "mipi-csi0-gate", "ahb_cam", 0x62100008,
+		     0, BIT(1), 0, 0);
+static SPRD_GATE_CLK(cphy1_gate,	"cphy1-gate",	"ahb-cam", 0x62100008,
+		     0, BIT(2), 0, 0);
+static SPRD_GATE_CLK(mipi_csi1,		"mipi-csi1",	"ahb-cam", 0x62100008,
+		     0, BIT(3), 0, 0);
+static SPRD_GATE_CLK(dcam0_axi_gate,	"dcam0-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(4), 0, 0);
+static SPRD_GATE_CLK(dcam1_axi_gate,	"dcam1-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(5), 0, 0);
+static SPRD_GATE_CLK(sensor0_gate,	"sensor0-gate",	"ahb-cam", 0x62100008,
+		     0, BIT(6), 0, 0);
+static SPRD_GATE_CLK(sensor1_gate,	"sensor1-gate",	"ahb-cam", 0x62100008,
+		     0, BIT(7), 0, 0);
+static SPRD_GATE_CLK(jpg0_axi_gate,	"jpg0-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(8), 0, 0);
+static SPRD_GATE_CLK(gpg1_axi_gate,	"gpg1-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(9), 0, 0);
+static SPRD_GATE_CLK(isp0_axi_gate,	"isp0-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(10), 0, 0);
+static SPRD_GATE_CLK(isp1_axi_gate,	"isp1-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(11), 0, 0);
+static SPRD_GATE_CLK(isp2_axi_gate,	"isp2-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(12), 0, 0);
+static SPRD_GATE_CLK(cpp_axi_gate,	"cpp-axi-gate",	"ahb-cam", 0x62100008,
+		     0, BIT(13), 0, 0);
+static SPRD_GATE_CLK(d0_if_axi_gate,	"d0-if-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(14), 0, 0);
+static SPRD_GATE_CLK(d2i_if_axi_gate, "d2i-if-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(15), 0, 0);
+static SPRD_GATE_CLK(i2d_if_axi_gate, "i2d-if-axi-gate", "ahb_cam", 0x62100008,
+		     0, BIT(16), 0, 0);
+static SPRD_GATE_CLK(spare_axi_gate, "spare-axi-gate",	"ahb_cam", 0x62100008,
+		     0, BIT(17), 0, 0);
+static SPRD_GATE_CLK(sensor2_gate, "sensor2-gate",	"ahb-cam", 0x62100008,
+		     0, BIT(18), 0, 0);
+
+static SPRD_GATE_CLK(d0if_in_d_en, "d0if-in-d-en", "ahb-cam", 0x62100028,
+		     0x1000, BIT(0), 0, 0);
+static SPRD_GATE_CLK(d1if_in_d_en, "d1if-in-d-en", "ahb-cam", 0x62100028,
+		     0x1000, BIT(1), 0, 0);
+static SPRD_GATE_CLK(d0if_in_d2i_en, "d0if-in-d2i-en", "ahb_cam", 0x62100028,
+		     0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(d1if_in_d2i_en, "d1if-in-d2i-en",	"ahb_cam", 0x62100028,
+		     0x1000, BIT(3), 0, 0);
+static SPRD_GATE_CLK(ia_in_d2i_en, "ia-in-d2i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(4), 0, 0);
+static SPRD_GATE_CLK(ib_in_d2i_en,	"ib-in-d2i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(5), 0, 0);
+static SPRD_GATE_CLK(ic_in_d2i_en,	"ic-in-d2i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(6), 0, 0);
+static SPRD_GATE_CLK(ia_in_i_en,	"ia-in-i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(7), 0, 0);
+static SPRD_GATE_CLK(ib_in_i_en,	"ib-in-i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(8), 0, 0);
+static SPRD_GATE_CLK(ic_in_i_en,	"ic-in-i-en",	"ahb-cam", 0x62100028,
+		     0x1000, BIT(9), 0, 0);
+
+static SPRD_GATE_CLK(dispc0_eb,		"dispc0-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(0), 0, 0);
+static SPRD_GATE_CLK(dispc1_eb,		"dispc1-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(1), 0, 0);
+static SPRD_GATE_CLK(dispc_mmu_eb,	"dispc-mmu-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(2), 0, 0);
+static SPRD_GATE_CLK(gsp0_eb,		"gsp0-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(3), 0, 0);
+static SPRD_GATE_CLK(gsp1_eb,		"gsp1-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(4), 0, 0);
+static SPRD_GATE_CLK(gsp0_mmu_eb,	"gsp0-mmu-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(5), 0, 0);
+static SPRD_GATE_CLK(gsp1_mmu_eb,	"gsp1-mmu-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(6), 0, 0);
+static SPRD_GATE_CLK(dsi0_eb,		"dsi0-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(7), 0, 0);
+static SPRD_GATE_CLK(dsi1_eb,		"dsi1-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(8), 0, 0);
+static SPRD_GATE_CLK(disp_ckg_eb,	"disp-ckg-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(9), 0, 0);
+static SPRD_GATE_CLK(disp_gpu_eb,	"disp-gpu-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(10), 0, 0);
+static SPRD_GATE_CLK(gpu_mtx_eb,	"gpu-mtx-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(13), 0, 0);
+static SPRD_GATE_CLK(gsp_mtx_eb,	"gsp-mtx-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(14), 0, 0);
+static SPRD_GATE_CLK(tmc_mtx_eb,	"tmc-mtx-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(15), 0, 0);
+static SPRD_GATE_CLK(dispc_mtx_eb,	"dispc-mtx-eb",	"ahb-disp", 0x63100000,
+		     0x1000, BIT(16), 0, 0);
+
+static SPRD_GATE_CLK(dphy0_gate,	"dphy0-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(0), 0, 0);
+static SPRD_GATE_CLK(dphy1_gate,	"dphy1-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(1), 0, 0);
+static SPRD_GATE_CLK(gsp0_a_gate,	"gsp0-a-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(2), 0, 0);
+static SPRD_GATE_CLK(gsp1_a_gate,	"gsp1-a-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(3), 0, 0);
+static SPRD_GATE_CLK(gsp0_f_gate,	"gsp0-f-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(4), 0, 0);
+static SPRD_GATE_CLK(gsp1_f_gate,	"gsp1-f-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(5), 0, 0);
+static SPRD_GATE_CLK(d_mtx_f_gate,	"d-mtx-f-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(6), 0, 0);
+static SPRD_GATE_CLK(d_mtx_a_gate,	"d-mtx-a-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(7), 0, 0);
+static SPRD_GATE_CLK(d_noc_f_gate,	"d-noc-f-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(8), 0, 0);
+static SPRD_GATE_CLK(d_noc_a_gate,	"d-noc-a-gate",	"ahb-disp", 0x63100008,
+		     0, BIT(9), 0, 0);
+static SPRD_GATE_CLK(gsp_mtx_f_gate, "gsp-mtx-f-gate", "ahb-disp", 0x63100008,
+		     0, BIT(10), 0, 0);
+static SPRD_GATE_CLK(gsp_mtx_a_gate, "gsp-mtx-a-gate", "ahb-disp", 0x63100008,
+		     0, BIT(11), 0, 0);
+static SPRD_GATE_CLK(gsp_noc_f_gate, "gsp-noc-f-gate", "ahb-disp", 0x63100008,
+		     0, BIT(12), 0, 0);
+static SPRD_GATE_CLK(gsp_noc_a_gate, "gsp-noc-a-gate", "ahb-disp", 0x63100008,
+		     0, BIT(13), 0, 0);
+static SPRD_GATE_CLK(dispm0idle_gate, "dispm0idle-gate", "ahb-disp", 0x63100008,
+		     0, BIT(14), 0, 0);
+static SPRD_GATE_CLK(gspm0idle_gate, "gspm0idle-gate", "ahb-disp", 0x63100008,
+		     0, BIT(15), 0, 0);
+static SPRD_GATE_CLK(sim0_eb,	"sim0-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(0), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(iis0_eb,	"iis0-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(1), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(iis1_eb,	"iis1-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(iis2_eb,	"iis2-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(3), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(iis3_eb,	"iis3-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(4), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(spi0_eb,	"spi0-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(5), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(spi1_eb,	"spi1-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(6), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(spi2_eb,	"spi2-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(7), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c0_eb,	"i2c0-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(8), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c1_eb,	"i2c1-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(9), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c2_eb,	"i2c2-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(10), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c3_eb,	"i2c3-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(11), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c4_eb,	"i2c4-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(12), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(i2c5_eb,	"i2c5-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(13), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(uart0_eb,	"uart0-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(uart1_eb,	"uart1-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(15), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(uart2_eb,	"uart2-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(16), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(uart3_eb,	"uart3-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(17), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(uart4_eb,	"uart4-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(ap_ckg_eb,	"ap-ckg-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(19), CLK_IGNORE_UNUSED, 0);
+static SPRD_GATE_CLK(spi3_eb,	"spi3-eb",	"ap_apb", 0x70b00000,
+		     0x1000, BIT(20), CLK_IGNORE_UNUSED, 0);
+
+static struct sprd_clk_common *sc9860_clk_clks[] = {
+	&rpll0_gate.common,
+	&rpll1_gate.common,
+	&mpll0_gate.common,
+	&mpll1_gate.common,
+	&dpll0_gate.common,
+	&dpll1_gate.common,
+	&gpll_gate.common,
+	&cppll_gate.common,
+	&ltepll0_gate.common,
+	&ltepll1_gate.common,
+	&twpll_gate.common,
+	&rpll0_clk.common,
+	&rpll1_clk.common,
+	&mpll0_clk.common,
+	&mpll1_clk.common,
+	&dpll0_clk.common,
+	&dpll1_clk.common,
+	&gpll_clk.common,
+	&cppll_clk.common,
+	&ltepll0_clk.common,
+	&ltepll1_clk.common,
+	&twpll_clk.common,
+	&aon_apb.common,
+	&aux0_clk.common,
+	&aux1_clk.common,
+	&aux2_clk.common,
+	&probe_clk.common,
+	&sp_ahb.common,
+	&cci_clk.common,
+	&gic_clk.common,
+	&cssys_clk.common,
+	&sdio0_2x.common,
+	&sdio1_2x.common,
+	&sdio2_2x.common,
+	&emmc_2x.common,
+	&uart0_clk.common,
+	&uart1_clk.common,
+	&uart2_clk.common,
+	&uart3_clk.common,
+	&uart4_clk.common,
+	&i2c0_clk.common,
+	&i2c1_clk.common,
+	&i2c2_clk.common,
+	&i2c3_clk.common,
+	&i2c4_clk.common,
+	&i2c5_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&spi2_clk.common,
+	&spi3_clk.common,
+	&iis0_clk.common,
+	&iis1_clk.common,
+	&iis2_clk.common,
+	&iis3_clk.common,
+	&lit_mcu.common,
+	&big_mcu.common,
+	&gpu_clk.common,
+	&vsp_clk.common,
+	&vsp_enc.common,
+	&dispc0_dpi.common,
+	&dispc1_dpi.common,
+	&sensor0_clk.common,
+	&sensor1_clk.common,
+	&sensor2_clk.common,
+	&sdio0_1x.common,
+	&sdio1_1x.common,
+	&sdio2_1x.common,
+	&emmc_1x.common,
+	&adi_clk.common,
+	&pwm0_clk.common,
+	&pwm1_clk.common,
+	&pwm2_clk.common,
+	&pwm3_clk.common,
+	&efuse_clk.common,
+	&cm3_uart0.common,
+	&cm3_uart1.common,
+	&thm_clk.common,
+	&cm3_i2c0.common,
+	&cm3_i2c1.common,
+	&cm4_spi.common,
+	&aon_i2c.common,
+	&avs_clk.common,
+	&ca53_dap.common,
+	&ca53_ts.common,
+	&djtag_tck.common,
+	&pmu_clk.common,
+	&pmu_26m.common,
+	&debounce_clk.common,
+	&otg2_ref.common,
+	&usb3_ref.common,
+	&ap_axi.common,
+	&ap_apb.common,
+	&ahb_vsp.common,
+	&ahb_disp.common,
+	&ahb_cam.common,
+	&mipi_csi0_eb.common,
+	&mipi_csi1_eb.common,
+	&usb3_eb.common,
+	&usb3_suspend.common,
+	&usb3_ref_eb.common,
+	&dma_eb.common,
+	&sdio0_eb.common,
+	&sdio1_eb.common,
+	&sdio2_eb.common,
+	&emmc_eb.common,
+	&rom_eb.common,
+	&busmon_eb.common,
+	&cc63s_eb.common,
+	&cc63p_eb.common,
+	&ce0_eb.common,
+	&ce1_eb.common,
+	&avs_lit_eb.common,
+	&avs_big_eb.common,
+	&ap_intc5_eb.common,
+	&gpio_eb.common,
+	&pwm0_eb.common,
+	&pwm1_eb.common,
+	&pwm2_eb.common,
+	&pwm3_eb.common,
+	&kpd_eb.common,
+	&aon_sys_eb.common,
+	&ap_sys_eb.common,
+	&aon_tmr_eb.common,
+	&ap_tmr0_eb.common,
+	&efuse_eb.common,
+	&eic_eb.common,
+	&pub1_reg_eb.common,
+	&adi_eb.common,
+	&ap_intc0_eb.common,
+	&ap_intc1_eb.common,
+	&ap_intc2_eb.common,
+	&ap_intc3_eb.common,
+	&ap_intc4_eb.common,
+	&splk_eb.common,
+	&mspi_eb.common,
+	&pub0_reg_eb.common,
+	&pin_eb.common,
+	&aon_ckg_eb.common,
+	&gpu_eb.common,
+	&apcpu_ts0_eb.common,
+	&apcpu_ts1_eb.common,
+	&dap_eb.common,
+	&i2c_eb.common,
+	&pmu_eb.common,
+	&thm_eb.common,
+	&aux0_eb.common,
+	&aux1_eb.common,
+	&aux2_eb.common,
+	&probe_eb.common,
+	&gpu0_avs_eb.common,
+	&gpu1_avs_eb.common,
+	&apcpu_wdg_eb.common,
+	&ap_tmr1_eb.common,
+	&ap_tmr2_eb.common,
+	&disp_emc_eb.common,
+	&zip_emc_eb.common,
+	&gsp_emc_eb.common,
+	&osc_aon_eb.common,
+	&lvds_trx_eb.common,
+	&lvds_tcxo_eb.common,
+	&mdar_eb.common,
+	&rtc4m0_cal_eb.common,
+	&rct100m_cal_eb.common,
+	&djtag_eb.common,
+	&mbox_eb.common,
+	&aon_dma_eb.common,
+	&dbg_emc_eb.common,
+	&lvds_pll_div_en.common,
+	&def_eb.common,
+	&aon_apb_rsv0.common,
+	&orp_jtag_eb.common,
+	&vsp_eb.common,
+	&cam_eb.common,
+	&disp_eb.common,
+	&dbg_axi_if_eb.common,
+	&sdio0_2x_en.common,
+	&sdio1_2x_en.common,
+	&sdio2_2x_en.common,
+	&emmc_2x_en.common,
+	&agcp_iis0_eb.common,
+	&agcp_iis1_eb.common,
+	&agcp_iis2_eb.common,
+	&agcp_iis3_eb.common,
+	&agcp_uart_eb.common,
+	&agcp_dmacp_eb.common,
+	&agcp_dmaap_eb.common,
+	&agcp_arc48k_eb.common,
+	&agcp_src44p1k_eb.common,
+	&agcp_mcdt_eb.common,
+	&agcp_vbcifd_eb.common,
+	&agcp_vbc_eb.common,
+	&agcp_spinlock_eb.common,
+	&agcp_icu_eb.common,
+	&agcp_ap_ashb_eb.common,
+	&agcp_cp_ashb_eb.common,
+	&agcp_aud_eb.common,
+	&agcp_audif_eb.common,
+	&vsp_dec_eb.common,
+	&vsp_ckg_eb.common,
+	&vsp_mmu_eb.common,
+	&vsp_enc_eb.common,
+	&vpp_eb.common,
+	&vsp_26m_eb.common,
+	&vsp_axi_gate.common,
+	&vsp_enc_gate.common,
+	&vpp_axi_gate.common,
+	&vsp_bm_gate.common,
+	&vsp_enc_bm_gate.common,
+	&vpp_bm_gate.common,
+	&dcam0_eb.common,
+	&dcam1_eb.common,
+	&isp0_eb.common,
+	&csi0_eb.common,
+	&csi1_eb.common,
+	&jpg0_eb.common,
+	&jpg1_eb.common,
+	&cam_ckg_eb.common,
+	&cam_mmu_eb.common,
+	&isp1_eb.common,
+	&cpp_eb.common,
+	&mmu_pf_eb.common,
+	&isp2_eb.common,
+	&dcam2isp_if_eb.common,
+	&isp2dcam_if_eb.common,
+	&isp_lclk_eb.common,
+	&isp_iclk_eb.common,
+	&isp_mclk_eb.common,
+	&isp_pclk_eb.common,
+	&isp_isp2dcam_eb.common,
+	&dcam0_if_eb.common,
+	&clk26m_if_eb.common,
+	&cphy0_gate.common,
+	&mipi_csi0_gate.common,
+	&cphy1_gate.common,
+	&mipi_csi1.common,
+	&dcam0_axi_gate.common,
+	&dcam1_axi_gate.common,
+	&sensor0_gate.common,
+	&sensor1_gate.common,
+	&jpg0_axi_gate.common,
+	&gpg1_axi_gate.common,
+	&isp0_axi_gate.common,
+	&isp1_axi_gate.common,
+	&isp2_axi_gate.common,
+	&cpp_axi_gate.common,
+	&d0_if_axi_gate.common,
+	&d2i_if_axi_gate.common,
+	&i2d_if_axi_gate.common,
+	&spare_axi_gate.common,
+	&sensor2_gate.common,
+	&d0if_in_d_en.common,
+	&d1if_in_d_en.common,
+	&d0if_in_d2i_en.common,
+	&d1if_in_d2i_en.common,
+	&ia_in_d2i_en.common,
+	&ib_in_d2i_en.common,
+	&ic_in_d2i_en.common,
+	&ia_in_i_en.common,
+	&ib_in_i_en.common,
+	&ic_in_i_en.common,
+	&dispc0_eb.common,
+	&dispc1_eb.common,
+	&dispc_mmu_eb.common,
+	&gsp0_eb.common,
+	&gsp1_eb.common,
+	&gsp0_mmu_eb.common,
+	&gsp1_mmu_eb.common,
+	&dsi0_eb.common,
+	&dsi1_eb.common,
+	&disp_ckg_eb.common,
+	&disp_gpu_eb.common,
+	&gpu_mtx_eb.common,
+	&gsp_mtx_eb.common,
+	&tmc_mtx_eb.common,
+	&dispc_mtx_eb.common,
+	&dphy0_gate.common,
+	&dphy1_gate.common,
+	&gsp0_a_gate.common,
+	&gsp1_a_gate.common,
+	&gsp0_f_gate.common,
+	&gsp1_f_gate.common,
+	&d_mtx_f_gate.common,
+	&d_mtx_a_gate.common,
+	&d_noc_f_gate.common,
+	&d_noc_a_gate.common,
+	&gsp_mtx_f_gate.common,
+	&gsp_mtx_a_gate.common,
+	&gsp_noc_f_gate.common,
+	&gsp_noc_a_gate.common,
+	&dispm0idle_gate.common,
+	&gspm0idle_gate.common,
+	&sim0_eb.common,
+	&iis0_eb.common,
+	&iis1_eb.common,
+	&iis2_eb.common,
+	&iis3_eb.common,
+	&spi0_eb.common,
+	&spi1_eb.common,
+	&spi2_eb.common,
+	&i2c0_eb.common,
+	&i2c1_eb.common,
+	&i2c2_eb.common,
+	&i2c3_eb.common,
+	&i2c4_eb.common,
+	&i2c5_eb.common,
+	&uart0_eb.common,
+	&uart1_eb.common,
+	&uart2_eb.common,
+	&uart3_eb.common,
+	&uart4_eb.common,
+	&ap_ckg_eb.common,
+	&spi3_eb.common,
+};
+
+static struct clk_hw_onecell_data sc9860_hw_clks = {
+	.hws	= {
+		[CLK_EXT_RCO_100M]	= &ext_rco_100m.hw,
+		[CLK_EXT_32K]		= &ext_32k.hw,
+		[CLK_FAC_4M]		= &fac_4m.hw,
+		[CLK_FAC_2M]		= &fac_2m.hw,
+		[CLK_FAC_1M]		= &fac_1m.hw,
+		[CLK_FAC_250K]		= &fac_250k.hw,
+		[CLK_FAC_RPLL0_26M]	= &fac_rpll0_26m.hw,
+		[CLK_FAC_RPLL1_26M]	= &fac_rpll1_26m.hw,
+		[CLK_FAC_RCO25M]	= &fac_rco_25m.hw,
+		[CLK_FAC_RCO4M]		= &fac_rco_4m.hw,
+		[CLK_FAC_RCO2M]		= &fac_rco_2m.hw,
+		[CLK_FAC_3K2]		= &fac_3k2.hw,
+		[CLK_FAC_1K]		= &fac_1k.hw,
+		[CLK_RPLL0_GATE]	= &rpll0_gate.common.hw,
+		[CLK_RPLL1_GATE]	= &rpll1_gate.common.hw,
+		[CLK_MPLL0_GATE]	= &mpll0_gate.common.hw,
+		[CLK_MPLL1_GATE]	= &mpll1_gate.common.hw,
+		[CLK_DPLL0_GATE]	= &dpll0_gate.common.hw,
+		[CLK_DPLL1_GATE]	= &dpll1_gate.common.hw,
+		[CLK_GPLL_GATE]		= &gpll_gate.common.hw,
+		[CLK_CPPLL_GATE]	= &cppll_gate.common.hw,
+		[CLK_LTEPLL0_GATE]	= &ltepll0_gate.common.hw,
+		[CLK_LTEPLL1_GATE]	= &ltepll1_gate.common.hw,
+		[CLK_TWPLL_GATE]	= &twpll_gate.common.hw,
+		[CLK_RPLL0]		= &rpll0_clk.common.hw,
+		[CLK_RPLL1]		= &rpll1_clk.common.hw,
+		[CLK_MPLL0]		= &mpll0_clk.common.hw,
+		[CLK_MPLL1]		= &mpll1_clk.common.hw,
+		[CLK_DPLL0]		= &dpll0_clk.common.hw,
+		[CLK_DPLL1]		= &dpll1_clk.common.hw,
+		[CLK_GPLL]		= &gpll_clk.common.hw,
+		[CLK_CPPLL]		= &cppll_clk.common.hw,
+		[CLK_LTEPLL0]		= &ltepll0_clk.common.hw,
+		[CLK_LTEPLL1]		= &ltepll1_clk.common.hw,
+		[CLK_TWPLL]		= &twpll_clk.common.hw,
+		[CLK_GPLL_42M5]		= &gpll_42m5.hw,
+		[CLK_TWPLL_768M]	= &twpll_768m.hw,
+		[CLK_TWPLL_384M]	= &twpll_384m.hw,
+		[CLK_TWPLL_192M]	= &twpll_192m.hw,
+		[CLK_TWPLL_96M]		= &twpll_96m.hw,
+		[CLK_TWPLL_48M]		= &twpll_48m.hw,
+		[CLK_TWPLL_24M]		= &twpll_24m.hw,
+		[CLK_TWPLL_12M]		= &twpll_12m.hw,
+		[CLK_TWPLL_512M]	= &twpll_512m.hw,
+		[CLK_TWPLL_256M]	= &twpll_256m.hw,
+		[CLK_TWPLL_128M]	= &twpll_128m.hw,
+		[CLK_TWPLL_64M]		= &twpll_64m.hw,
+		[CLK_TWPLL_307M2]	= &twpll_307m2.hw,
+		[CLK_TWPLL_153M6]	= &twpll_153m6.hw,
+		[CLK_TWPLL_76M8]	= &twpll_76m8.hw,
+		[CLK_TWPLL_51M2]	= &twpll_51m2.hw,
+		[CLK_TWPLL_38M4]	= &twpll_38m4.hw,
+		[CLK_TWPLL_19M2]	= &twpll_19m2.hw,
+		[CLK_L0_614M4]		= &l0_614m4.hw,
+		[CLK_L0_409M6]		= &l0_409m6.hw,
+		[CLK_L0_38M]		= &l0_38m.hw,
+		[CLK_L1_38M]		= &l1_38m.hw,
+		[CLK_RPLL0_192M]	= &rpll0_192m.hw,
+		[CLK_RPLL0_96M]		= &rpll0_96m.hw,
+		[CLK_RPLL0_48M]		= &rpll0_48m.hw,
+		[CLK_RPLL1_468M]	= &rpll1_468m.hw,
+		[CLK_RPLL1_192M]	= &rpll1_192m.hw,
+		[CLK_RPLL1_96M]		= &rpll1_96m.hw,
+		[CLK_RPLL1_64M]		= &rpll1_64m.hw,
+		[CLK_RPLL1_48M]		= &rpll1_48m.hw,
+		[CLK_DPLL0_50M]		= &dpll0_50m.hw,
+		[CLK_DPLL1_50M]		= &dpll1_50m.hw,
+		[CLK_CPPLL_50M]		= &cppll_50m.hw,
+		[CLK_M0_39M]		= &m0_39m.hw,
+		[CLK_M1_63M]		= &m1_63m.hw,
+		[CLK_AON_APB]		= &aon_apb.common.hw,
+		[CLK_AUX0]		= &aux0_clk.common.hw,
+		[CLK_AUX1]		= &aux1_clk.common.hw,
+		[CLK_AUX2]		= &aux2_clk.common.hw,
+		[CLK_PROBE]		= &probe_clk.common.hw,
+		[CLK_SP_AHB]		= &sp_ahb.common.hw,
+		[CLK_CCI]		= &cci_clk.common.hw,
+		[CLK_GIC]		= &gic_clk.common.hw,
+		[CLK_CSSYS]		= &cssys_clk.common.hw,
+		[CLK_SDIO0_2X]		= &sdio0_2x.common.hw,
+		[CLK_SDIO1_2X]		= &sdio1_2x.common.hw,
+		[CLK_SDIO2_2X]		= &sdio2_2x.common.hw,
+		[CLK_EMMC_2X]		= &emmc_2x.common.hw,
+		[CLK_UART0]		= &uart0_clk.common.hw,
+		[CLK_UART1]		= &uart1_clk.common.hw,
+		[CLK_UART2]		= &uart2_clk.common.hw,
+		[CLK_UART3]		= &uart3_clk.common.hw,
+		[CLK_UART4]		= &uart4_clk.common.hw,
+		[CLK_I2C0]		= &i2c0_clk.common.hw,
+		[CLK_I2C1]		= &i2c1_clk.common.hw,
+		[CLK_I2C2]		= &i2c2_clk.common.hw,
+		[CLK_I2C3]		= &i2c3_clk.common.hw,
+		[CLK_I2C4]		= &i2c4_clk.common.hw,
+		[CLK_I2C5]		= &i2c5_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_SPI3]		= &spi3_clk.common.hw,
+		[CLK_IIS0]		= &iis0_clk.common.hw,
+		[CLK_IIS1]		= &iis1_clk.common.hw,
+		[CLK_IIS2]		= &iis2_clk.common.hw,
+		[CLK_IIS3]		= &iis3_clk.common.hw,
+		[CLK_LIT_MCU]		= &lit_mcu.common.hw,
+		[CLK_BIG_MCU]		= &big_mcu.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_VSP]		= &vsp_clk.common.hw,
+		[CLK_VSP_ENC]		= &vsp_enc.common.hw,
+		[CLK_DISPC0_DPI]	= &dispc0_dpi.common.hw,
+		[CLK_DISPC1_DPI]	= &dispc1_dpi.common.hw,
+		[CLK_SENSOR0]		= &sensor0_clk.common.hw,
+		[CLK_SENSOR1]		= &sensor1_clk.common.hw,
+		[CLK_SENSOR2]		= &sensor2_clk.common.hw,
+		[CLK_SDIO0_1X]		= &sdio0_1x.common.hw,
+		[CLK_SDIO1_1X]		= &sdio1_1x.common.hw,
+		[CLK_SDIO2_1X]		= &sdio2_1x.common.hw,
+		[CLK_EMMC_1X]		= &emmc_1x.common.hw,
+		[CLK_ADI]		= &adi_clk.common.hw,
+		[CLK_PWM0]		= &pwm0_clk.common.hw,
+		[CLK_PWM1]		= &pwm1_clk.common.hw,
+		[CLK_PWM2]		= &pwm2_clk.common.hw,
+		[CLK_PWM3]		= &pwm3_clk.common.hw,
+		[CLK_EFUSE]		= &efuse_clk.common.hw,
+		[CLK_CM3_UART0]		= &cm3_uart0.common.hw,
+		[CLK_CM3_UART1]		= &cm3_uart1.common.hw,
+		[CLK_THM]		= &thm_clk.common.hw,
+		[CLK_CM3_I2C0]		= &cm3_i2c0.common.hw,
+		[CLK_CM3_I2C1]		= &cm3_i2c1.common.hw,
+		[CLK_CM4_SPI]		= &cm4_spi.common.hw,
+		[CLK_AON_I2C]		= &aon_i2c.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_CA53_DAP]		= &ca53_dap.common.hw,
+		[CLK_CA53_TS]		= &ca53_ts.common.hw,
+		[CLK_DJTAG_TCK]		= &djtag_tck.common.hw,
+		[CLK_PMU]		= &pmu_clk.common.hw,
+		[CLK_PMU_26M]		= &pmu_26m.common.hw,
+		[CLK_DEBOUNCE]		= &debounce_clk.common.hw,
+		[CLK_OTG2_REF]		= &otg2_ref.common.hw,
+		[CLK_USB3_REF]		= &usb3_ref.common.hw,
+		[CLK_AP_AXI]		= &ap_axi.common.hw,
+		[CLK_AP_APB]		= &ap_apb.common.hw,
+		[CLK_AHB_VSP]		= &ahb_vsp.common.hw,
+		[CLK_AHB_DISP]		= &ahb_disp.common.hw,
+		[CLK_AHB_CAM]		= &ahb_cam.common.hw,
+		[CLK_MIPI_CSI0_EB]	= &mipi_csi0_eb.common.hw,
+		[CLK_MIPI_CSI1_EB]	= &mipi_csi1_eb.common.hw,
+		[CLK_USB3_EB]		= &usb3_eb.common.hw,
+		[CLK_USB3_SUSPEND_EB]	= &usb3_suspend.common.hw,
+		[CLK_USB3_REF_EB]	= &usb3_ref_eb.common.hw,
+		[CLK_DMA_EB]		= &dma_eb.common.hw,
+		[CLK_SDIO0_EB]		= &sdio0_eb.common.hw,
+		[CLK_SDIO1_EB]		= &sdio1_eb.common.hw,
+		[CLK_SDIO2_EB]		= &sdio2_eb.common.hw,
+		[CLK_EMMC_EB]		= &emmc_eb.common.hw,
+		[CLK_ROM_EB]		= &rom_eb.common.hw,
+		[CLK_BUSMON_EB]		= &busmon_eb.common.hw,
+		[CLK_CC63S_EB]		= &cc63s_eb.common.hw,
+		[CLK_CC63P_EB]		= &cc63p_eb.common.hw,
+		[CLK_CE0_EB]		= &ce0_eb.common.hw,
+		[CLK_CE1_EB]		= &ce1_eb.common.hw,
+		[CLK_AVS_LIT_EB]	= &avs_lit_eb.common.hw,
+		[CLK_AVS_BIG_EB]	= &avs_big_eb.common.hw,
+		[CLK_AP_INTC5_EB]	= &ap_intc5_eb.common.hw,
+		[CLK_GPIO_EB]		= &gpio_eb.common.hw,
+		[CLK_PWM0_EB]		= &pwm0_eb.common.hw,
+		[CLK_PWM1_EB]		= &pwm1_eb.common.hw,
+		[CLK_PWM2_EB]		= &pwm2_eb.common.hw,
+		[CLK_PWM3_EB]		= &pwm3_eb.common.hw,
+		[CLK_KPD_EB]		= &kpd_eb.common.hw,
+		[CLK_AON_SYS_EB]	= &aon_sys_eb.common.hw,
+		[CLK_AP_SYS_EB]		= &ap_sys_eb.common.hw,
+		[CLK_AON_TMR_EB]	= &aon_tmr_eb.common.hw,
+		[CLK_AP_TMR0_EB]	= &ap_tmr0_eb.common.hw,
+		[CLK_EFUSE_EB]		= &efuse_eb.common.hw,
+		[CLK_EIC_EB]		= &eic_eb.common.hw,
+		[CLK_PUB1_REG_EB]	= &pub1_reg_eb.common.hw,
+		[CLK_ADI_EB]		= &adi_eb.common.hw,
+		[CLK_AP_INTC0_EB]	= &ap_intc0_eb.common.hw,
+		[CLK_AP_INTC1_EB]	= &ap_intc1_eb.common.hw,
+		[CLK_AP_INTC2_EB]	= &ap_intc2_eb.common.hw,
+		[CLK_AP_INTC3_EB]	= &ap_intc3_eb.common.hw,
+		[CLK_AP_INTC4_EB]	= &ap_intc4_eb.common.hw,
+		[CLK_SPLK_EB]		= &splk_eb.common.hw,
+		[CLK_MSPI_EB]		= &mspi_eb.common.hw,
+		[CLK_PUB0_REG_EB]	= &pub0_reg_eb.common.hw,
+		[CLK_PIN_EB]		= &pin_eb.common.hw,
+		[CLK_AON_CKG_EB]	= &aon_ckg_eb.common.hw,
+		[CLK_GPU_EB]		= &gpu_eb.common.hw,
+		[CLK_APCPU_TS0_EB]	= &apcpu_ts0_eb.common.hw,
+		[CLK_APCPU_TS1_EB]	= &apcpu_ts1_eb.common.hw,
+		[CLK_DAP_EB]		= &dap_eb.common.hw,
+		[CLK_I2C_EB]		= &i2c_eb.common.hw,
+		[CLK_PMU_EB]		= &pmu_eb.common.hw,
+		[CLK_THM_EB]		= &thm_eb.common.hw,
+		[CLK_AUX0_EB]		= &aux0_eb.common.hw,
+		[CLK_AUX1_EB]		= &aux1_eb.common.hw,
+		[CLK_AUX2_EB]		= &aux2_eb.common.hw,
+		[CLK_PROBE_EB]		= &probe_eb.common.hw,
+		[CLK_GPU0_AVS_EB]	= &gpu0_avs_eb.common.hw,
+		[CLK_GPU1_AVS_EB]	= &gpu1_avs_eb.common.hw,
+		[CLK_APCPU_WDG_EB]	= &apcpu_wdg_eb.common.hw,
+		[CLK_AP_TMR1_EB]	= &ap_tmr1_eb.common.hw,
+		[CLK_AP_TMR2_EB]	= &ap_tmr2_eb.common.hw,
+		[CLK_DISP_EMC_EB]	= &disp_emc_eb.common.hw,
+		[CLK_ZIP_EMC_EB]	= &zip_emc_eb.common.hw,
+		[CLK_GSP_EMC_EB]	= &gsp_emc_eb.common.hw,
+		[CLK_OSC_AON_EB]	= &osc_aon_eb.common.hw,
+		[CLK_LVDS_TRX_EB]	= &lvds_trx_eb.common.hw,
+		[CLK_LVDS_TCXO_EB]	= &lvds_tcxo_eb.common.hw,
+		[CLK_MDAR_EB]		= &mdar_eb.common.hw,
+		[CLK_RTC4M0_CAL_EB]	= &rtc4m0_cal_eb.common.hw,
+		[CLK_RCT100M_CAL_EB]	= &rct100m_cal_eb.common.hw,
+		[CLK_DJTAG_EB]		= &djtag_eb.common.hw,
+		[CLK_MBOX_EB]		= &mbox_eb.common.hw,
+		[CLK_AON_DMA_EB]	= &aon_dma_eb.common.hw,
+		[CLK_DBG_EMC_EB]	= &dbg_emc_eb.common.hw,
+		[CLK_LVDS_PLL_DIV_EN]	= &lvds_pll_div_en.common.hw,
+		[CLK_DEF_EB]		= &def_eb.common.hw,
+		[CLK_AON_APB_RSV0]	= &aon_apb_rsv0.common.hw,
+		[CLK_ORP_JTAG_EB]	= &orp_jtag_eb.common.hw,
+		[CLK_VSP_EB]		= &vsp_eb.common.hw,
+		[CLK_CAM_EB]		= &cam_eb.common.hw,
+		[CLK_DISP_EB]		= &disp_eb.common.hw,
+		[CLK_DBG_AXI_IF_EB]	= &dbg_axi_if_eb.common.hw,
+			[CLK_SDIO0_2X_EN]	= &sdio0_2x_en.common.hw,
+			[CLK_SDIO1_2X_EN]	= &sdio1_2x_en.common.hw,
+			[CLK_SDIO2_2X_EN]	= &sdio2_2x_en.common.hw,
+			[CLK_EMMC_2X_EN]	= &emmc_2x_en.common.hw,
+		[CLK_AGCP_IIS0_EB]	= &agcp_iis0_eb.common.hw,
+		[CLK_AGCP_IIS1_EB]	= &agcp_iis1_eb.common.hw,
+		[CLK_AGCP_IIS2_EB]	= &agcp_iis2_eb.common.hw,
+		[CLK_AGCP_IIS3_EB]	= &agcp_iis3_eb.common.hw,
+		[CLK_AGCP_UART_EB]	= &agcp_uart_eb.common.hw,
+		[CLK_AGCP_DMACP_EB]	= &agcp_dmacp_eb.common.hw,
+		[CLK_AGCP_DMAAP_EB]	= &agcp_dmaap_eb.common.hw,
+		[CLK_AGCP_ARC48K_EB]	= &agcp_arc48k_eb.common.hw,
+		[CLK_AGCP_SRC44P1K_EB]	= &agcp_src44p1k_eb.common.hw,
+		[CLK_AGCP_MCDT_EB]	= &agcp_mcdt_eb.common.hw,
+		[CLK_AGCP_VBCIFD_EB]	= &agcp_vbcifd_eb.common.hw,
+		[CLK_AGCP_VBC_EB]	= &agcp_vbc_eb.common.hw,
+		[CLK_AGCP_SPINLOCK_EB]	= &agcp_spinlock_eb.common.hw,
+		[CLK_AGCP_ICU_EB]	= &agcp_icu_eb.common.hw,
+		[CLK_AGCP_AP_ASHB_EB]	= &agcp_ap_ashb_eb.common.hw,
+		[CLK_AGCP_CP_ASHB_EB]	= &agcp_cp_ashb_eb.common.hw,
+		[CLK_AGCP_AUD_EB]	= &agcp_aud_eb.common.hw,
+		[CLK_AGCP_AUDIF_EB]	= &agcp_audif_eb.common.hw,
+		[CLK_VSP_DEC_EB]	= &vsp_dec_eb.common.hw,
+		[CLK_VSP_CKG_EB]	= &vsp_ckg_eb.common.hw,
+		[CLK_VSP_MMU_EB]	= &vsp_mmu_eb.common.hw,
+		[CLK_VSP_ENC_EB]	= &vsp_enc_eb.common.hw,
+		[CLK_VPP_EB]		= &vpp_eb.common.hw,
+		[CLK_VSP_26M_EB]	= &vsp_26m_eb.common.hw,
+		[CLK_VSP_AXI_GATE]	= &vsp_axi_gate.common.hw,
+		[CLK_VSP_ENC_GATE]	= &vsp_enc_gate.common.hw,
+		[CLK_VPP_AXI_GATE]	= &vpp_axi_gate.common.hw,
+		[CLK_VSP_BM_GATE]	= &vsp_bm_gate.common.hw,
+		[CLK_VSP_ENC_BM_GATE]	= &vsp_enc_bm_gate.common.hw,
+		[CLK_VPP_BM_GATE]	= &vpp_bm_gate.common.hw,
+		[CLK_DCAM0_EB]		= &dcam0_eb.common.hw,
+		[CLK_DCAM1_EB]		= &dcam1_eb.common.hw,
+		[CLK_ISP0_EB]		= &isp0_eb.common.hw,
+		[CLK_CSI0_EB]		= &csi0_eb.common.hw,
+		[CLK_CSI1_EB]		= &csi1_eb.common.hw,
+		[CLK_JPG0_EB]		= &jpg0_eb.common.hw,
+		[CLK_JPG1_EB]		= &jpg1_eb.common.hw,
+		[CLK_CAM_CKG_EB]	= &cam_ckg_eb.common.hw,
+		[CLK_CAM_MMU_EB]	= &cam_mmu_eb.common.hw,
+		[CLK_ISP1_EB]		= &isp1_eb.common.hw,
+		[CLK_CPP_EB]		= &cpp_eb.common.hw,
+		[CLK_MMU_PF_EB]		= &mmu_pf_eb.common.hw,
+		[CLK_ISP2_EB]		= &isp2_eb.common.hw,
+		[CLK_DCAM2ISP_IF_EB]	= &dcam2isp_if_eb.common.hw,
+		[CLK_ISP2DCAM_IF_EB]	= &isp2dcam_if_eb.common.hw,
+		[CLK_ISP_LCLK_EB]	= &isp_lclk_eb.common.hw,
+		[CLK_ISP_ICLK_EB]	= &isp_iclk_eb.common.hw,
+		[CLK_ISP_MCLK_EB]	= &isp_mclk_eb.common.hw,
+		[CLK_ISP_PCLK_EB]	= &isp_pclk_eb.common.hw,
+		[CLK_ISP_ISP2DCAM_EB]	= &isp_isp2dcam_eb.common.hw,
+		[CLK_DCAM0_IF_EB]	= &dcam0_if_eb.common.hw,
+		[CLK_CLK26M_IF_EB]	= &clk26m_if_eb.common.hw,
+		[CLK_CPHY0_GATE]	= &cphy0_gate.common.hw,
+		[CLK_MIPI_CSI0_GATE]	= &mipi_csi0_gate.common.hw,
+		[CLK_CPHY1_GATE]	= &cphy1_gate.common.hw,
+		[CLK_MIPI_CSI1]		= &mipi_csi1.common.hw,
+		[CLK_DCAM0_AXI_GATE]	= &dcam0_axi_gate.common.hw,
+		[CLK_DCAM1_AXI_GATE]	= &dcam1_axi_gate.common.hw,
+		[CLK_SENSOR0_GATE]	= &sensor0_gate.common.hw,
+		[CLK_SENSOR1_GATE]	= &sensor1_gate.common.hw,
+		[CLK_JPG0_AXI_GATE]	= &jpg0_axi_gate.common.hw,
+		[CLK_GPG1_AXI_GATE]	= &gpg1_axi_gate.common.hw,
+		[CLK_ISP0_AXI_GATE]	= &isp0_axi_gate.common.hw,
+		[CLK_ISP1_AXI_GATE]	= &isp1_axi_gate.common.hw,
+		[CLK_ISP2_AXI_GATE]	= &isp2_axi_gate.common.hw,
+		[CLK_CPP_AXI_GATE]	= &cpp_axi_gate.common.hw,
+		[CLK_D0_IF_AXI_GATE]	= &d0_if_axi_gate.common.hw,
+		[CLK_D2I_IF_AXI_GATE]	= &d2i_if_axi_gate.common.hw,
+		[CLK_I2D_IF_AXI_GATE]	= &i2d_if_axi_gate.common.hw,
+		[CLK_SPARE_AXI_GATE]	= &spare_axi_gate.common.hw,
+		[CLK_SENSOR2_GATE]	= &sensor2_gate.common.hw,
+		[CLK_D0IF_IN_D_EN]	= &d0if_in_d_en.common.hw,
+		[CLK_D1IF_IN_D_EN]	= &d1if_in_d_en.common.hw,
+		[CLK_D0IF_IN_D2I_EN]	= &d0if_in_d2i_en.common.hw,
+		[CLK_D1IF_IN_D2I_EN]	= &d1if_in_d2i_en.common.hw,
+		[CLK_IA_IN_D2I_EN]	= &ia_in_d2i_en.common.hw,
+		[CLK_IB_IN_D2I_EN]	= &ib_in_d2i_en.common.hw,
+		[CLK_IC_IN_D2I_EN]	= &ic_in_d2i_en.common.hw,
+		[CLK_IA_IN_I_EN]	= &ia_in_i_en.common.hw,
+		[CLK_IB_IN_I_EN]	= &ib_in_i_en.common.hw,
+		[CLK_IC_IN_I_EN]	= &ic_in_i_en.common.hw,
+		[CLK_DISPC0_EB]		= &dispc0_eb.common.hw,
+		[CLK_DISPC1_EB]		= &dispc1_eb.common.hw,
+		[CLK_DISPC_MMU_EB]	= &dispc_mmu_eb.common.hw,
+		[CLK_GSP0_EB]		= &gsp0_eb.common.hw,
+		[CLK_GSP1_EB]		= &gsp1_eb.common.hw,
+		[CLK_GSP0_MMU_EB]	= &gsp0_mmu_eb.common.hw,
+		[CLK_GSP1_MMU_EB]	= &gsp1_mmu_eb.common.hw,
+		[CLK_DSI0_EB]		= &dsi0_eb.common.hw,
+		[CLK_DSI1_EB]		= &dsi1_eb.common.hw,
+		[CLK_DISP_CKG_EB]	= &disp_ckg_eb.common.hw,
+		[CLK_DISP_GPU_EB]	= &disp_gpu_eb.common.hw,
+		[CLK_GPU_MTX_EB]	= &gpu_mtx_eb.common.hw,
+		[CLK_GSP_MTX_EB]	= &gsp_mtx_eb.common.hw,
+		[CLK_TMC_MTX_EB]	= &tmc_mtx_eb.common.hw,
+		[CLK_DISPC_MTX_EB]	= &dispc_mtx_eb.common.hw,
+		[CLK_DPHY0_GATE]	= &dphy0_gate.common.hw,
+		[CLK_DPHY1_GATE]	= &dphy1_gate.common.hw,
+		[CLK_GSP0_A_GATE]	= &gsp0_a_gate.common.hw,
+		[CLK_GSP1_A_GATE]	= &gsp1_a_gate.common.hw,
+		[CLK_GSP0_F_GATE]	= &gsp0_f_gate.common.hw,
+		[CLK_GSP1_F_GATE]	= &gsp1_f_gate.common.hw,
+		[CLK_D_MTX_F_GATE]	= &d_mtx_f_gate.common.hw,
+		[CLK_D_MTX_A_GATE]	= &d_mtx_a_gate.common.hw,
+		[CLK_D_NOC_F_GATE]	= &d_noc_f_gate.common.hw,
+		[CLK_D_NOC_A_GATE]	= &d_noc_a_gate.common.hw,
+		[CLK_GSP_MTX_F_GATE]	= &gsp_mtx_f_gate.common.hw,
+		[CLK_GSP_MTX_A_GATE]	= &gsp_mtx_a_gate.common.hw,
+		[CLK_GSP_NOC_F_GATE]	= &gsp_noc_f_gate.common.hw,
+		[CLK_GSP_NOC_A_GATE]	= &gsp_noc_a_gate.common.hw,
+		[CLK_DISPM0IDLE_GATE]	= &dispm0idle_gate.common.hw,
+		[CLK_GSPM0IDLE_GATE]	= &gspm0idle_gate.common.hw,
+		[CLK_SIM0_EB]		= &sim0_eb.common.hw,
+		[CLK_IIS0_EB]		= &iis0_eb.common.hw,
+		[CLK_IIS1_EB]		= &iis1_eb.common.hw,
+		[CLK_IIS2_EB]		= &iis2_eb.common.hw,
+		[CLK_IIS3_EB]		= &iis3_eb.common.hw,
+		[CLK_SPI0_EB]		= &spi0_eb.common.hw,
+		[CLK_SPI1_EB]		= &spi1_eb.common.hw,
+		[CLK_SPI2_EB]		= &spi2_eb.common.hw,
+		[CLK_I2C0_EB]		= &i2c0_eb.common.hw,
+		[CLK_I2C1_EB]		= &i2c1_eb.common.hw,
+		[CLK_I2C2_EB]		= &i2c2_eb.common.hw,
+		[CLK_I2C3_EB]		= &i2c3_eb.common.hw,
+		[CLK_I2C4_EB]		= &i2c4_eb.common.hw,
+		[CLK_I2C5_EB]		= &i2c5_eb.common.hw,
+		[CLK_UART0_EB]		= &uart0_eb.common.hw,
+		[CLK_UART1_EB]		= &uart1_eb.common.hw,
+		[CLK_UART2_EB]		= &uart2_eb.common.hw,
+		[CLK_UART3_EB]		= &uart3_eb.common.hw,
+		[CLK_UART4_EB]		= &uart4_eb.common.hw,
+		[CLK_AP_CKG_EB]		= &ap_ckg_eb.common.hw,
+		[CLK_SPI3_EB]		= &spi3_eb.common.hw,
+	},
+	.num	= CLK_NUMBER_SC9860,
+};
+
+static const struct sprd_clk_desc sc9860_clk_desc = {
+	.clk_clks	= sc9860_clk_clks,
+	.num_clk_clks	= ARRAY_SIZE(sc9860_clk_clks),
+
+	.hw_clks	= &sc9860_hw_clks,
+};
+
+static int sc9860_clk_probe(struct platform_device *pdev)
+{
+	void __iomem *base;
+	unsigned int i, count = pdev->num_resources;
+	int ret = 0;
+	struct resource *res;
+	struct clk_addr_map *sc9860_maps;
+
+	sc9860_maps = kcalloc(count, sizeof(*sc9860_maps), GFP_KERNEL);
+	if (!sc9860_maps)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		base = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(base)) {
+			ret = PTR_ERR(base);
+			goto free_maps;
+		}
+
+		sc9860_maps[i].phy = res->start & 0xffff0000;
+		sc9860_maps[i].virt = base;
+	}
+
+	ret = sprd_clk_probe(pdev->dev.of_node, sc9860_maps,
+			     count, &sc9860_clk_desc);
+	if (ret)
+		goto free_maps;
+
+	pr_info("SC9860: %u clocks have been registered now.\n",
+		CLK_NUMBER_SC9860);
+
+free_maps:
+	kfree(sc9860_maps);
+	return ret;
+}
+
+static const struct of_device_id sc9860_clk_ids[] = {
+	{ .compatible = "sprd,sc9860-clk" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sc9860_clk_ids);
+
+static struct platform_driver sc9860_clk_driver = {
+	.probe	= sc9860_clk_probe,
+	.driver	= {
+		.name	= "sc9860-clk",
+		.of_match_table	= sc9860_clk_ids,
+	},
+};
+//builtin_platform_driver(sc9860_clk_driver);
+module_platform_driver(sc9860_clk_driver);
+
+MODULE_DESCRIPTION("Spreadtrum SC9860 Clock Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sc9860-clk");
diff --git a/include/dt-bindings/clock/sprd,sc9860-clk.h b/include/dt-bindings/clock/sprd,sc9860-clk.h
new file mode 100644
index 0000000..79b2404
--- /dev/null
+++ b/include/dt-bindings/clock/sprd,sc9860-clk.h
@@ -0,0 +1,375 @@
+/*
+ * Spreadtrum SC9860 platform clocks
+ *
+ * Copyright (C) 2017, Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#ifndef _DT_BINDINGS_CLK_SC9860_H_
+#define _DT_BINDINGS_CLK_SC9860_H_
+
+#define	CLK_EXT_RCO_100M		0
+#define	CLK_EXT_32K			1
+#define	CLK_FAC_4M			2
+#define	CLK_FAC_2M			3
+#define	CLK_FAC_1M			4
+#define	CLK_FAC_250K			5
+#define	CLK_FAC_RPLL0_26M		6
+#define	CLK_FAC_RPLL1_26M		7
+#define	CLK_FAC_RCO25M			8
+#define	CLK_FAC_RCO4M			9
+#define	CLK_FAC_RCO2M			10
+#define	CLK_FAC_3K2			11
+#define	CLK_FAC_1K			12
+#define	CLK_RPLL0_GATE			13
+#define	CLK_RPLL1_GATE			14
+#define	CLK_MPLL0_GATE			15
+#define	CLK_MPLL1_GATE			16
+#define	CLK_DPLL0_GATE			17
+#define	CLK_DPLL1_GATE			18
+#define	CLK_GPLL_GATE			19
+#define	CLK_CPPLL_GATE			20
+#define	CLK_LTEPLL0_GATE		21
+#define	CLK_LTEPLL1_GATE		22
+#define	CLK_TWPLL_GATE			23
+#define	CLK_RPLL0			24
+#define	CLK_RPLL1			25
+#define	CLK_MPLL0			26
+#define	CLK_MPLL1			27
+#define	CLK_DPLL0			28
+#define	CLK_DPLL1			29
+#define	CLK_GPLL			30
+#define	CLK_CPPLL			31
+#define	CLK_LTEPLL0			32
+#define	CLK_LTEPLL1			33
+#define	CLK_TWPLL			34
+#define	CLK_GPLL_42M5			35
+#define	CLK_TWPLL_768M			36
+#define	CLK_TWPLL_384M			37
+#define	CLK_TWPLL_192M			38
+#define	CLK_TWPLL_96M			39
+#define	CLK_TWPLL_48M			40
+#define	CLK_TWPLL_24M			41
+#define	CLK_TWPLL_12M			42
+#define	CLK_TWPLL_512M			43
+#define	CLK_TWPLL_256M			44
+#define	CLK_TWPLL_128M			45
+#define	CLK_TWPLL_64M			46
+#define	CLK_TWPLL_307M2			47
+#define	CLK_TWPLL_153M6			48
+#define	CLK_TWPLL_76M8			49
+#define	CLK_TWPLL_51M2			50
+#define	CLK_TWPLL_38M4			51
+#define	CLK_TWPLL_19M2			52
+#define	CLK_L0_614M4			53
+#define	CLK_L0_409M6			54
+#define	CLK_L0_38M			55
+#define	CLK_L1_38M			56
+#define	CLK_RPLL0_192M			57
+#define	CLK_RPLL0_96M			58
+#define	CLK_RPLL0_48M			59
+#define	CLK_RPLL1_468M			60
+#define	CLK_RPLL1_192M			61
+#define	CLK_RPLL1_96M			62
+#define	CLK_RPLL1_64M			63
+#define	CLK_RPLL1_48M			64
+#define	CLK_DPLL0_50M			65
+#define	CLK_DPLL1_50M			66
+#define	CLK_CPPLL_50M			67
+#define	CLK_M0_39M			68
+#define	CLK_M1_63M			69
+#define	CLK_AON_APB			70
+#define	CLK_AUX0			71
+#define	CLK_AUX1			72
+#define	CLK_AUX2			73
+#define	CLK_PROBE			74
+#define	CLK_SP_AHB			75
+#define	CLK_CCI				76
+#define	CLK_GIC				77
+#define	CLK_CSSYS			78
+#define	CLK_SDIO0_2X			79
+#define	CLK_SDIO1_2X			80
+#define	CLK_SDIO2_2X			81
+#define	CLK_EMMC_2X			82
+#define	CLK_UART0			83
+#define	CLK_UART1			84
+#define	CLK_UART2			85
+#define	CLK_UART3			86
+#define	CLK_UART4			87
+#define	CLK_I2C0			88
+#define	CLK_I2C1			89
+#define	CLK_I2C2			90
+#define	CLK_I2C3			91
+#define	CLK_I2C4			92
+#define	CLK_I2C5			93
+#define	CLK_SPI0			94
+#define	CLK_SPI1			95
+#define	CLK_SPI2			96
+#define	CLK_SPI3			97
+#define	CLK_IIS0			98
+#define	CLK_IIS1			99
+#define	CLK_IIS2			100
+#define	CLK_IIS3			101
+#define	CLK_LIT_MCU			102
+#define	CLK_BIG_MCU			103
+#define	CLK_GPU				104
+#define	CLK_VSP				105
+#define	CLK_VSP_ENC			106
+#define	CLK_DISPC0_DPI			107
+#define	CLK_DISPC1_DPI			108
+#define	CLK_SENSOR0			109
+#define	CLK_SENSOR1			110
+#define	CLK_SENSOR2			111
+#define	CLK_SDIO0_1X			112
+#define	CLK_SDIO1_1X			113
+#define	CLK_SDIO2_1X			114
+#define	CLK_EMMC_1X			115
+#define	CLK_ADI				116
+#define	CLK_PWM0			117
+#define	CLK_PWM1			118
+#define	CLK_PWM2			119
+#define	CLK_PWM3			120
+#define	CLK_EFUSE			121
+#define	CLK_CM3_UART0			122
+#define	CLK_CM3_UART1			123
+#define	CLK_THM				124
+#define	CLK_CM3_I2C0			125
+#define	CLK_CM3_I2C1			126
+#define	CLK_CM4_SPI			127
+#define	CLK_AON_I2C			128
+#define	CLK_AVS				129
+#define	CLK_CA53_DAP			130
+#define	CLK_CA53_TS			131
+#define	CLK_DJTAG_TCK			132
+#define	CLK_PMU				133
+#define	CLK_PMU_26M			134
+#define	CLK_DEBOUNCE			135
+#define	CLK_OTG2_REF			136
+#define	CLK_USB3_REF			137
+#define	CLK_AP_AXI			138
+#define	CLK_AP_APB			139
+#define	CLK_AHB_VSP			140
+#define	CLK_AHB_DISP			141
+#define	CLK_AHB_CAM			142
+#define	CLK_MIPI_CSI0_EB		143
+#define	CLK_MIPI_CSI1_EB		144
+#define	CLK_USB3_EB			145
+#define	CLK_USB3_SUSPEND_EB		146
+#define	CLK_USB3_REF_EB			147
+#define	CLK_DMA_EB			148
+#define	CLK_SDIO0_EB			149
+#define	CLK_SDIO1_EB			150
+#define	CLK_SDIO2_EB			151
+#define	CLK_EMMC_EB			152
+#define	CLK_ROM_EB			153
+#define	CLK_BUSMON_EB			154
+#define	CLK_CC63S_EB			155
+#define	CLK_CC63P_EB			156
+#define	CLK_CE0_EB			157
+#define	CLK_CE1_EB			158
+#define	CLK_AVS_LIT_EB			159
+#define	CLK_AVS_BIG_EB			160
+#define	CLK_AP_INTC5_EB			161
+#define	CLK_GPIO_EB			162
+#define	CLK_PWM0_EB			163
+#define	CLK_PWM1_EB			164
+#define	CLK_PWM2_EB			165
+#define	CLK_PWM3_EB			166
+#define	CLK_KPD_EB			167
+#define	CLK_AON_SYS_EB			168
+#define	CLK_AP_SYS_EB			169
+#define	CLK_AON_TMR_EB			170
+#define	CLK_AP_TMR0_EB			171
+#define	CLK_EFUSE_EB			172
+#define	CLK_EIC_EB			173
+#define	CLK_PUB1_REG_EB			174
+#define	CLK_ADI_EB			175
+#define	CLK_AP_INTC0_EB			176
+#define	CLK_AP_INTC1_EB			177
+#define	CLK_AP_INTC2_EB			178
+#define	CLK_AP_INTC3_EB			179
+#define	CLK_AP_INTC4_EB			180
+#define	CLK_SPLK_EB			181
+#define	CLK_MSPI_EB			182
+#define	CLK_PUB0_REG_EB			183
+#define	CLK_PIN_EB			184
+#define	CLK_AON_CKG_EB			185
+#define	CLK_GPU_EB			186
+#define	CLK_APCPU_TS0_EB		187
+#define	CLK_APCPU_TS1_EB		188
+#define	CLK_DAP_EB			189
+#define	CLK_I2C_EB			190
+#define	CLK_PMU_EB			191
+#define	CLK_THM_EB			192
+#define	CLK_AUX0_EB			193
+#define	CLK_AUX1_EB			194
+#define	CLK_AUX2_EB			195
+#define	CLK_PROBE_EB			196
+#define	CLK_GPU0_AVS_EB			197
+#define	CLK_GPU1_AVS_EB			198
+#define	CLK_APCPU_WDG_EB		199
+#define	CLK_AP_TMR1_EB			200
+#define	CLK_AP_TMR2_EB			201
+#define	CLK_DISP_EMC_EB			202
+#define	CLK_ZIP_EMC_EB			203
+#define	CLK_GSP_EMC_EB			204
+#define	CLK_OSC_AON_EB			205
+#define	CLK_LVDS_TRX_EB			206
+#define	CLK_LVDS_TCXO_EB		207
+#define	CLK_MDAR_EB			208
+#define	CLK_RTC4M0_CAL_EB		209
+#define	CLK_RCT100M_CAL_EB		210
+#define	CLK_DJTAG_EB			211
+#define	CLK_MBOX_EB			212
+#define	CLK_AON_DMA_EB			213
+#define	CLK_DBG_EMC_EB			214
+#define	CLK_LVDS_PLL_DIV_EN		215
+#define	CLK_DEF_EB			216
+#define	CLK_AON_APB_RSV0		217
+#define	CLK_ORP_JTAG_EB			218
+#define	CLK_VSP_EB			219
+#define	CLK_CAM_EB			220
+#define	CLK_DISP_EB			221
+#define	CLK_DBG_AXI_IF_EB		222
+#define	CLK_SDIO0_2X_EN			223
+#define	CLK_SDIO1_2X_EN			224
+#define	CLK_SDIO2_2X_EN			225
+#define	CLK_EMMC_2X_EN			226
+#define	CLK_AGCP_IIS0_EB		227
+#define	CLK_AGCP_IIS1_EB		228
+#define	CLK_AGCP_IIS2_EB		229
+#define	CLK_AGCP_IIS3_EB		230
+#define	CLK_AGCP_UART_EB		231
+#define	CLK_AGCP_DMACP_EB		232
+#define	CLK_AGCP_DMAAP_EB		233
+#define	CLK_AGCP_ARC48K_EB		234
+#define	CLK_AGCP_SRC44P1K_EB		235
+#define	CLK_AGCP_MCDT_EB		236
+#define	CLK_AGCP_VBCIFD_EB		237
+#define	CLK_AGCP_VBC_EB			238
+#define	CLK_AGCP_SPINLOCK_EB		239
+#define	CLK_AGCP_ICU_EB			240
+#define	CLK_AGCP_AP_ASHB_EB		241
+#define	CLK_AGCP_CP_ASHB_EB		242
+#define	CLK_AGCP_AUD_EB			243
+#define	CLK_AGCP_AUDIF_EB		244
+#define	CLK_VSP_DEC_EB			245
+#define	CLK_VSP_CKG_EB			246
+#define	CLK_VSP_MMU_EB			247
+#define	CLK_VSP_ENC_EB			248
+#define	CLK_VPP_EB			249
+#define	CLK_VSP_26M_EB			250
+#define	CLK_VSP_AXI_GATE		251
+#define	CLK_VSP_ENC_GATE		252
+#define	CLK_VPP_AXI_GATE		253
+#define	CLK_VSP_BM_GATE			254
+#define	CLK_VSP_ENC_BM_GATE		255
+#define	CLK_VPP_BM_GATE			256
+#define	CLK_DCAM0_EB			257
+#define	CLK_DCAM1_EB			258
+#define	CLK_ISP0_EB			259
+#define	CLK_CSI0_EB			260
+#define	CLK_CSI1_EB			261
+#define	CLK_JPG0_EB			262
+#define	CLK_JPG1_EB			263
+#define	CLK_CAM_CKG_EB			264
+#define	CLK_CAM_MMU_EB			265
+#define	CLK_ISP1_EB			266
+#define	CLK_CPP_EB			267
+#define	CLK_MMU_PF_EB			268
+#define	CLK_ISP2_EB			269
+#define	CLK_DCAM2ISP_IF_EB		270
+#define	CLK_ISP2DCAM_IF_EB		271
+#define	CLK_ISP_LCLK_EB			272
+#define	CLK_ISP_ICLK_EB			273
+#define	CLK_ISP_MCLK_EB			274
+#define	CLK_ISP_PCLK_EB			275
+#define	CLK_ISP_ISP2DCAM_EB		276
+#define	CLK_DCAM0_IF_EB			277
+#define	CLK_CLK26M_IF_EB		278
+#define	CLK_CPHY0_GATE			279
+#define	CLK_MIPI_CSI0_GATE		280
+#define	CLK_CPHY1_GATE			281
+#define	CLK_MIPI_CSI1			282
+#define	CLK_DCAM0_AXI_GATE		283
+#define	CLK_DCAM1_AXI_GATE		284
+#define	CLK_SENSOR0_GATE		285
+#define	CLK_SENSOR1_GATE		286
+#define	CLK_JPG0_AXI_GATE		287
+#define	CLK_GPG1_AXI_GATE		288
+#define	CLK_ISP0_AXI_GATE		289
+#define	CLK_ISP1_AXI_GATE		290
+#define	CLK_ISP2_AXI_GATE		291
+#define	CLK_CPP_AXI_GATE		292
+#define	CLK_D0_IF_AXI_GATE		293
+#define	CLK_D2I_IF_AXI_GATE		294
+#define	CLK_I2D_IF_AXI_GATE		295
+#define	CLK_SPARE_AXI_GATE		296
+#define	CLK_SENSOR2_GATE		297
+#define	CLK_D0IF_IN_D_EN		298
+#define	CLK_D1IF_IN_D_EN		299
+#define	CLK_D0IF_IN_D2I_EN		300
+#define	CLK_D1IF_IN_D2I_EN		301
+#define	CLK_IA_IN_D2I_EN		302
+#define	CLK_IB_IN_D2I_EN		303
+#define	CLK_IC_IN_D2I_EN		304
+#define	CLK_IA_IN_I_EN			305
+#define	CLK_IB_IN_I_EN			306
+#define	CLK_IC_IN_I_EN			307
+#define	CLK_DISPC0_EB			308
+#define	CLK_DISPC1_EB			309
+#define	CLK_DISPC_MMU_EB		310
+#define	CLK_GSP0_EB			311
+#define	CLK_GSP1_EB			312
+#define	CLK_GSP0_MMU_EB			313
+#define	CLK_GSP1_MMU_EB			314
+#define	CLK_DSI0_EB			315
+#define	CLK_DSI1_EB			316
+#define	CLK_DISP_CKG_EB			317
+#define	CLK_DISP_GPU_EB			318
+#define	CLK_GPU_MTX_EB			319
+#define	CLK_GSP_MTX_EB			320
+#define	CLK_TMC_MTX_EB			321
+#define	CLK_DISPC_MTX_EB		322
+#define	CLK_DPHY0_GATE			323
+#define	CLK_DPHY1_GATE			324
+#define	CLK_GSP0_A_GATE			325
+#define	CLK_GSP1_A_GATE			326
+#define	CLK_GSP0_F_GATE			327
+#define	CLK_GSP1_F_GATE			328
+#define	CLK_D_MTX_F_GATE		329
+#define	CLK_D_MTX_A_GATE		330
+#define	CLK_D_NOC_F_GATE		331
+#define	CLK_D_NOC_A_GATE		332
+#define	CLK_GSP_MTX_F_GATE		333
+#define	CLK_GSP_MTX_A_GATE		334
+#define	CLK_GSP_NOC_F_GATE		335
+#define	CLK_GSP_NOC_A_GATE		336
+#define	CLK_DISPM0IDLE_GATE		337
+#define	CLK_GSPM0IDLE_GATE		338
+#define	CLK_SIM0_EB			339
+#define	CLK_IIS0_EB			340
+#define	CLK_IIS1_EB			341
+#define	CLK_IIS2_EB			342
+#define	CLK_IIS3_EB			343
+#define	CLK_SPI0_EB			344
+#define	CLK_SPI1_EB			345
+#define	CLK_SPI2_EB			346
+#define	CLK_I2C0_EB			347
+#define	CLK_I2C1_EB			348
+#define	CLK_I2C2_EB			349
+#define	CLK_I2C3_EB			350
+#define	CLK_I2C4_EB			351
+#define	CLK_I2C5_EB			352
+#define	CLK_UART0_EB			353
+#define	CLK_UART1_EB			354
+#define	CLK_UART2_EB			355
+#define	CLK_UART3_EB			356
+#define	CLK_UART4_EB			357
+#define	CLK_AP_CKG_EB			358
+#define	CLK_SPI3_EB			359
+
+#define	CLK_NUMBER_SC9860		(CLK_SPI3_EB + 1)
+
+#endif /* _DT_BINDINGS_CLK_SC9860_H_ */
-- 
2.7.4

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

* [PATCH V2 10/10] arm64: dts: add clocks for SC9860
  2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
                   ` (8 preceding siblings ...)
  2017-07-11 10:56 ` [PATCH V2 09/10] clk: sprd: add clocks support for SC9860 Chunyan Zhang
@ 2017-07-11 10:56 ` Chunyan Zhang
  9 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-11 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Now we have clock driver, so add clock devicetree data for SC9860.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
 arch/arm64/boot/dts/sprd/sc9860.dtsi | 22 ++++++++++++++++++++++
 arch/arm64/boot/dts/sprd/whale2.dtsi |  3 +--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi b/arch/arm64/boot/dts/sprd/sc9860.dtsi
index 7b7d8ce..8d3f549 100644
--- a/arch/arm64/boot/dts/sprd/sc9860.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi
@@ -7,6 +7,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sprd,sc9860-clk.h>
 #include "whale2.dtsi"
 
 / {
@@ -183,6 +184,27 @@
 	};
 
 	soc {
+		clk: clk {
+			compatible = "sprd,sc9860-clk";
+			#clock-cells = <1>;
+			reg = <0 0x20000000 0 0x400>,
+			      <0 0x20210000 0 0x3000>,
+			      <0 0x402b0000 0 0x4000>,
+			      <0 0x402d0000 0 0x400>,
+			      <0 0x402e0000 0 0x4000>,
+			      <0 0x40400000 0 0x400>,
+			      <0 0x40880000 0 0x400>,
+			      <0 0x415e0000 0 0x400>,
+			      <0 0x60200000 0 0x400>,
+			      <0 0x61000000 0 0x400>,
+			      <0 0x61100000 0 0x3000>,
+			      <0 0x62000000 0 0x4000>,
+			      <0 0x62100000 0 0x4000>,
+			      <0 0x63000000 0 0x400>,
+			      <0 0x63100000 0 0x3000>,
+			      <0 0x70b00000 0 0x3000>;
+		};
+
 		funnel at 10001000 { /* SoC Funnel */
 			compatible = "arm,coresight-funnel", "arm,primecell";
 			reg = <0 0x10001000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi
index 7c217c5..a4f376e 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -59,13 +59,12 @@
 				status = "disabled";
 			};
 		};
-
 	};
 
 	ext_26m: ext-26m {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <26000000>;
-		clock-output-names = "ext_26m";
+		clock-output-names = "ext-26m";
 	};
 };
-- 
2.7.4

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

* [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation
  2017-07-11 10:56 ` [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation Chunyan Zhang
@ 2017-07-14 16:10   ` Rob Herring
  2017-07-17  2:02     ` Chunyan Zhang
  2017-07-21 22:57   ` Stephen Boyd
  1 sibling, 1 reply; 15+ messages in thread
From: Rob Herring @ 2017-07-14 16:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 11, 2017 at 06:56:19PM +0800, Chunyan Zhang wrote:
> Introduce a new binding with its documentation for Spreadtrum clock
> sub-framework.
> 
> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
> ---
>  Documentation/devicetree/bindings/clock/sprd.txt | 36 ++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt

Acked-by: Rob Herring <robh@kernel.org>

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

* [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation
  2017-07-14 16:10   ` Rob Herring
@ 2017-07-17  2:02     ` Chunyan Zhang
  0 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-17  2:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 15 July 2017 at 00:10, Rob Herring <robh@kernel.org> wrote:
> On Tue, Jul 11, 2017 at 06:56:19PM +0800, Chunyan Zhang wrote:
>> Introduce a new binding with its documentation for Spreadtrum clock
>> sub-framework.
>>
>> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
>> ---
>>  Documentation/devicetree/bindings/clock/sprd.txt | 36 ++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
>
> Acked-by: Rob Herring <robh@kernel.org>

Thank you, Rob

Cheers,
Chunyan

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

* [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation
  2017-07-11 10:56 ` [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation Chunyan Zhang
  2017-07-14 16:10   ` Rob Herring
@ 2017-07-21 22:57   ` Stephen Boyd
  2017-07-25 10:27     ` Chunyan Zhang
  1 sibling, 1 reply; 15+ messages in thread
From: Stephen Boyd @ 2017-07-21 22:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/11, Chunyan Zhang wrote:
> Introduce a new binding with its documentation for Spreadtrum clock
> sub-framework.
> 
> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
> ---
>  Documentation/devicetree/bindings/clock/sprd.txt | 36 ++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/sprd.txt b/Documentation/devicetree/bindings/clock/sprd.txt
> new file mode 100644
> index 0000000..c6f3abf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/sprd.txt
> @@ -0,0 +1,36 @@
> +Spreadtrum Clock Binding
> +------------------------
> +
> +Required properties:
> +- compatible: must contain the following compatible:
> +	- "sprd,sc9860-clk" (only support SC9860 for the time being)
> +
> +- reg:	Must contain the registers base address and length.
> +	Clocks on most of Spreadtrum's SoCs were designed to locate in a few
> +	different address areas, so there would be more than one items under
> +	this property.
> +
> +- #clock-cells: must be 1
> +
> +Example:
> +
> +clk: clk {

clock-controller for the node name?

> +	compatible = "sprd,sc9860-clk";
> +	#clock-cells = <1>;
> +	reg = <0 0x20000000 0 0x400>,
> +	      <0 0x20210000 0 0x3000>,
> +	      <0 0x402b0000 0 0x4000>,
> +	      <0 0x402d0000 0 0x400>,
> +	      <0 0x402e0000 0 0x4000>,
> +	      <0 0x40400000 0 0x400>,
> +	      <0 0x40880000 0 0x400>,
> +	      <0 0x415e0000 0 0x400>,
> +	      <0 0x60200000 0 0x400>,
> +	      <0 0x61000000 0 0x400>,
> +	      <0 0x61100000 0 0x3000>,
> +	      <0 0x62000000 0 0x4000>,
> +	      <0 0x62100000 0 0x4000>,
> +	      <0 0x63000000 0 0x400>,
> +	      <0 0x63100000 0 0x3000>,
> +	      <0 0x70b00000 0 0x3000>;

I'm still suspecting that we need multiple nodes, for each device
the clocks are embedded in. Mediatek SoCs have a similar design,
and they have many nodes. Does it happen to always be in some
fixed offset inside the different devices that use the clks?

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

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

* [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation
  2017-07-21 22:57   ` Stephen Boyd
@ 2017-07-25 10:27     ` Chunyan Zhang
  0 siblings, 0 replies; 15+ messages in thread
From: Chunyan Zhang @ 2017-07-25 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stephen,

On 22 July 2017 at 06:57, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 07/11, Chunyan Zhang wrote:
>> Introduce a new binding with its documentation for Spreadtrum clock
>> sub-framework.
>>
>> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
>> ---
>>  Documentation/devicetree/bindings/clock/sprd.txt | 36 ++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/sprd.txt b/Documentation/devicetree/bindings/clock/sprd.txt
>> new file mode 100644
>> index 0000000..c6f3abf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/sprd.txt
>> @@ -0,0 +1,36 @@
>> +Spreadtrum Clock Binding
>> +------------------------
>> +
>> +Required properties:
>> +- compatible: must contain the following compatible:
>> +     - "sprd,sc9860-clk" (only support SC9860 for the time being)
>> +
>> +- reg:       Must contain the registers base address and length.
>> +     Clocks on most of Spreadtrum's SoCs were designed to locate in a few
>> +     different address areas, so there would be more than one items under
>> +     this property.
>> +
>> +- #clock-cells: must be 1
>> +
>> +Example:
>> +
>> +clk: clk {
>
> clock-controller for the node name?

Ah, sorry I forgot to address this.

>
>> +     compatible = "sprd,sc9860-clk";
>> +     #clock-cells = <1>;
>> +     reg = <0 0x20000000 0 0x400>,
>> +           <0 0x20210000 0 0x3000>,
>> +           <0 0x402b0000 0 0x4000>,
>> +           <0 0x402d0000 0 0x400>,
>> +           <0 0x402e0000 0 0x4000>,
>> +           <0 0x40400000 0 0x400>,
>> +           <0 0x40880000 0 0x400>,
>> +           <0 0x415e0000 0 0x400>,
>> +           <0 0x60200000 0 0x400>,
>> +           <0 0x61000000 0 0x400>,
>> +           <0 0x61100000 0 0x3000>,
>> +           <0 0x62000000 0 0x4000>,
>> +           <0 0x62100000 0 0x4000>,
>> +           <0 0x63000000 0 0x400>,
>> +           <0 0x63100000 0 0x3000>,
>> +           <0 0x70b00000 0 0x3000>;
>
> I'm still suspecting that we need multiple nodes, for each device
> the clocks are embedded in. Mediatek SoCs have a similar design,
> and they have many nodes. Does it happen to always be in some
> fixed offset inside the different devices that use the clks?

Unfortunately clock design on SC9860 is not the case.

>From the device tree file [1] which we're using internally, we can see
there're 9 ranges of clocks are located on the same address area with
syscons, they respectively are:
        <0 0x20210000 0 0x3000>,
        <0 0x402b0000 0 0x4000>,
        <0 0x402e0000 0 0x4000>,
        <0 0x40400000 0 0x400>,
        <0 0x415e0000 0 0x400>,
        <0 0x61100000 0 0x3000>,
        <0 0x62100000 0 0x4000>,
        <0 0x63100000 0 0x3000>,
        <0 0x70b00000 0 0x3000>;

others ranges (listed below) are only for clocks, neither same with
any devices nor syscons:

        <0 0x20000000 0 0x400>,  is for AP (application processor) clocks
        <0 0x402d0000 0 0x400>,  is for AON prediv clocks
        <0 0x40880000 0 0x400>,
        <0 0x60200000 0 0x400>,  is for GPU clocks
        <0 0x61000000 0 0x400>,  is for VSP clocks
        <0 0x62000000 0 0x4000>,is for camera clocks
        <0 0x63000000 0 0x400>,  is for display clocks

Let's see dcam as an example.
The dcam device is on 0x6220 0000 [2], while dcam clocks are on 0x6200
0000, and also some dcam clocks are on 0x6210 0000 which is the same
address area with a syscon called 'cam_ahb_controller' [3].

I can separate them into multiple nodes, and then there will be 16
clock nodes in dt, isn't it too much?

Which solution do you think is better for our case?


Thanks,
Chunyan


[1] https://github.com/sprdlinux/kernel/blob/sp9860g-1h10/arch/arm64/boot/dts/sprd/whale.dtsi#L29
[2] https://github.com/sprdlinux/kernel/blob/sp9860g-1h10/arch/arm64/boot/dts/sprd/sc9850s.dtsi#L372
[3] https://github.com/sprdlinux/kernel/blob/sp9860g-1h10/arch/arm64/boot/dts/sprd/whale.dtsi#L71

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

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

end of thread, other threads:[~2017-07-25 10:27 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-11 10:56 [PATCH V2 00/10] add clock driver for Spreadtrum platforms Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 01/10] drivers: move clock common macros out from vendor directories Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 02/10] dt-bindings: Add Spreadtrum clock binding documentation Chunyan Zhang
2017-07-14 16:10   ` Rob Herring
2017-07-17  2:02     ` Chunyan Zhang
2017-07-21 22:57   ` Stephen Boyd
2017-07-25 10:27     ` Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 03/10] clk: sprd: Add common infrastructure Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 04/10] clk: sprd: add gate clock support Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 05/10] clk: sprd: add mux " Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 06/10] clk: sprd: add divider " Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 07/10] clk: sprd: add composite " Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 08/10] clk: sprd: add adjustable pll support Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 09/10] clk: sprd: add clocks support for SC9860 Chunyan Zhang
2017-07-11 10:56 ` [PATCH V2 10/10] arm64: dts: add clocks " Chunyan Zhang

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