All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] support Hisilicon SoC
@ 2013-06-17  8:56 Haojian Zhuang
  2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v5:
1. Remove HIWORD clk patches since they're merged into clk git tree.
2. Set hisilicon,clk-reset property of clkgate node is optional.
3. Update on commandline args in DTS file. Remove earlyprintk, mem, nfs.
4. Move gpio-keys out of amba node in DTS file.

v4:
1. Add clk gate with HIWORD mask for Rockchip.
2. Update comments and code of HIWORD flags for mux/divider.
3. Append a mux without HIWORD mask in Hisilicon 3620.
4. Fix the pinmux setting in Hi4511.

v3:
1. Use clk_register_mux_table().

v2:
1. Reuse mux & divider driver. So append CLK_MUX_HIWORD_MASK &
CLK_DIVIDER_HIWORD_MASK for Hi3620 SoC.
2. Fix system timer running too fast because wrong divider is choosen.
3. Remove .init_irq in DT machine descriptor.

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-17  8:56 [PATCH v5 0/4] support Hisilicon SoC Haojian Zhuang
@ 2013-06-17  8:56 ` Haojian Zhuang
  2013-06-17 21:50   ` Olof Johansson
  2013-06-20 20:22   ` Mike Turquette
  2013-06-17  8:56 ` [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Add clock support with device tree on Hisilicon SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: Mike Turquette <mturquette@linaro.org>
---
 .../devicetree/bindings/clock/hisilicon.txt        |  66 ++++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-hi3xxx.c                           | 414 +++++++++++++++++++++
 3 files changed, 481 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
 create mode 100644 drivers/clk/clk-hi3xxx.c

diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
new file mode 100644
index 0000000..7f99805
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
@@ -0,0 +1,66 @@
+Device Tree Clock bindings for arch-hi3xxx
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties for mux clocks:
+ - compatible : Shall be "hisilicon,hi3620-clk-mux".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,clkmux-reg : array of mux register offset & mask bits
+ - hisilicon,clkmux-table : array of mux select bits
+
+Required properties for Hi3620 gate clocks:
+ - compatible : Shall be "hisilicon,hi3620-clk-gate".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,hi3620-clkgate : array of enable register offset & enable bits
+ - hisilicon,hi3620-clkreset : array of reset register offset & enable bits
+
+Required properties for clock divider:
+ - compatible : Shall be "hisilicon,hi3620-clk-div".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - #hisilicon,clkdiv-table-cells : the number of parameters after phandle in
+   hisilicon,clkdiv-table property.
+ - hisilicon,clkdiv-table : list of value that are used to configure clock
+   divider. They're value of phandle, index & divider value.
+ - hisilicon,clkdiv : array of divider register offset & mask bits.
+
+Required properties for gate clocks:
+ - compatible : Shall be "hisilicon,clk-gate".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,clkgate-inverted : bool value. True means that set-to-disable.
+
+For example:
+	timclk1: clkgate at 38 {
+		compatible = "hisilicon,clk-gate";
+		#clock-cells = <0>;
+		clocks = <&refclk_timer1>;
+		clock-output-names = "timclk1";
+		hisilicon,clkgate-inverted;
+		hisilicon,clkgate = <0 18>;
+	};
+
+	dtable: clkdiv at 0 {
+		#hisilicon,clkdiv-table-cells = <2>;
+	};
+
+	div_cfgaxi: clkdiv at 2 {
+		compatible = "hisilicon,hi3620-clk-div";
+		#clock-cells = <0>;
+		clocks = <&div_shareaxi>;
+		clock-output-names = "cfgAXI_div";
+		hisilicon,clkdiv-table = <&dtable 0x01 2>;
+		hisilicon,clkdiv = <0x100 0x60>;
+	};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 137d3e7..522e8d1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK)	+= clk-composite.o
 # SoCs specific
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835.o
 obj-$(CONFIG_ARCH_NOMADIK)	+= clk-nomadik.o
+obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3xxx.o
 obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs/
 obj-$(CONFIG_ARCH_SOCFPGA)	+= socfpga/
diff --git a/drivers/clk/clk-hi3xxx.c b/drivers/clk/clk-hi3xxx.c
new file mode 100644
index 0000000..14c2f80
--- /dev/null
+++ b/drivers/clk/clk-hi3xxx.c
@@ -0,0 +1,414 @@
+/*
+ * Hisilicon clock driver
+ *
+ * Copyright (c) 2012-2013 Hisilicon Limited.
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *	   Xin Li <li.xin@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#define HI3620_DISABLE_OFF		0x4
+#define HI3620_STATUS_OFF		0x8
+
+enum {
+	HI3620_SCTRL,
+	HI3XXX_MAX,
+};
+
+struct hi3620_periclk {
+	struct clk_hw	hw;
+	void __iomem	*enable;	/* enable register */
+	void __iomem	*reset;		/* reset register */
+	u32		ebits;		/* bits in enable/disable register */
+	u32		rbits;		/* bits in reset/unreset register */
+	spinlock_t	*lock;
+};
+
+struct hs_clk {
+	void __iomem	*pmctrl;
+	void __iomem	*sctrl;
+	spinlock_t	lock;
+};
+
+static void __iomem *hi3xxx_clk_base[HI3XXX_MAX];
+
+static DEFINE_SPINLOCK(hi3xxx_clk_lock);
+
+static const struct of_device_id hi3xxx_of_match[] = {
+	{ .compatible = "hisilicon,sctrl", .data = (void *)HI3620_SCTRL, },
+};
+
+static void __iomem __init *hi3xxx_init_clocks(struct device_node *np)
+{
+	struct device_node *parent;
+	const struct of_device_id *match;
+	void __iomem *ret = NULL;
+	int i;
+
+	parent = of_get_parent(np);
+	if (!parent)
+		goto out;
+	match = of_match_node(hi3xxx_of_match, parent);
+	if (!match)
+		goto out;
+
+	i = (unsigned int)match->data;
+	switch (i) {
+	case HI3620_SCTRL:
+		if (!hi3xxx_clk_base[i]) {
+			ret = of_iomap(parent, 0);
+			WARN_ON(!ret);
+			hi3xxx_clk_base[i] = ret;
+		} else {
+			ret = hi3xxx_clk_base[i];
+		}
+		break;
+	default:
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static int hi3620_clkgate_prepare(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	if (pclk->reset) {
+		writel_relaxed(pclk->rbits, pclk->reset + HI3620_DISABLE_OFF);
+		readl_relaxed(pclk->reset + HI3620_STATUS_OFF);
+	}
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+	return 0;
+}
+
+static int hi3620_clkgate_enable(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	writel_relaxed(pclk->ebits, pclk->enable);
+	readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+	return 0;
+}
+
+static void hi3620_clkgate_disable(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
+	readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+}
+
+static struct clk_ops hi3620_clkgate_ops = {
+	.prepare	= hi3620_clkgate_prepare,
+	.enable		= hi3620_clkgate_enable,
+	.disable	= hi3620_clkgate_disable,
+};
+
+static void __init hi3620_clkgate_setup(struct device_node *np)
+{
+	struct hi3620_periclk *pclk;
+	struct clk_init_data *init;
+	struct clk *clk;
+	const char *clk_name, *name, **parent_names;
+	u32 rdata[2], gdata[2];
+	void __iomem *base;
+
+	base = hi3xxx_init_clocks(np);
+	if (!base)
+		return;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,hi3620-clkgate",
+				       &gdata[0], 2))
+		return;
+
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		return;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	pclk = kzalloc(sizeof(*pclk), GFP_KERNEL);
+	if (!pclk)
+		goto err_pclk;
+
+	init = kzalloc(sizeof(*init), GFP_KERNEL);
+	if (!init)
+		goto err_init;
+	init->name = kstrdup(clk_name, GFP_KERNEL);
+	init->ops = &hi3620_clkgate_ops;
+	init->flags = CLK_SET_RATE_PARENT;
+	init->parent_names = parent_names;
+	init->num_parents = 1;
+
+	if (!of_property_read_u32_array(np, "hisilicon,hi3620-clkreset",
+					&rdata[0], 2)) {
+		pclk->reset = base + rdata[0];
+		pclk->rbits = rdata[1];
+	}
+	pclk->enable = base + gdata[0];
+	pclk->ebits = gdata[1];
+	pclk->lock = &hi3xxx_clk_lock;
+	pclk->hw.init = init;
+
+	clk = clk_register(NULL, &pclk->hw);
+	if (IS_ERR(clk))
+		goto err_clk;
+	if (!of_property_read_string(np, "clock-names", &name))
+		clk_register_clkdev(clk, name, NULL);
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err_clk:
+	kfree(init);
+err_init:
+	kfree(pclk);
+err_pclk:
+	kfree(parent_names);
+}
+CLK_OF_DECLARE(hi3620_gate, "hisilicon,hi3620-clk-gate", hi3620_clkgate_setup)
+
+static int __init hi3xxx_parse_mux(struct device_node *np,
+				   u8 *num_parents,
+				   u32 *table)
+{
+	int i, cnt, ret;
+
+	/* get the count of items in mux */
+	for (i = 0, cnt = 0; ; i++, cnt++) {
+		/* parent's #clock-cells property is always 0 */
+		if (!of_parse_phandle(np, "clocks", i))
+			break;
+	}
+
+	for (i = 0; i < cnt; i++) {
+		if (!of_clk_get_parent_name(np, i))
+			return -ENOENT;
+	}
+	*num_parents = cnt;
+	table = kzalloc(sizeof(u32 *) * cnt, GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+	ret = of_property_read_u32_array(np, "hisilicon,clkmux-table",
+					 table, cnt);
+	if (ret)
+		goto err;
+	return 0;
+err:
+	kfree(table);
+	return ret;
+}
+
+static void __init clkmux_setup(struct device_node *np, int mode)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names = NULL;
+	u32 rdata[2], mask, *table = NULL;
+	u8 num_parents, shift, clk_mux_flags = 0;
+	void __iomem *reg, *base;
+	int i, ret;
+
+	base = hi3xxx_init_clocks(np);
+	if (!base)
+		return;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,clkmux-reg",
+				       &rdata[0], 2))
+		return;
+	ret = hi3xxx_parse_mux(np, &num_parents, table);
+	if (ret)
+		return;
+
+	parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+	if (!parent_names)
+		goto err;
+	for (i = 0; i < num_parents; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+
+	reg = base + rdata[0];
+	shift = ffs(rdata[1]) - 1;
+	mask = rdata[1] >> shift;
+	if (mode)
+		clk_mux_flags = CLK_MUX_HIWORD_MASK;
+	clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents,
+				     CLK_SET_RATE_PARENT, reg, shift, mask,
+				     clk_mux_flags, table, &hi3xxx_clk_lock);
+	if (IS_ERR(clk))
+		goto err_clk;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+	return;
+err_clk:
+	kfree(parent_names);
+err:
+	kfree(table);
+}
+
+static void __init hi3620_clkmux_setup(struct device_node *np)
+{
+	clkmux_setup(np, 1);
+}
+CLK_OF_DECLARE(hi3620_mux, "hisilicon,hi3620-clk-mux", hi3620_clkmux_setup)
+
+static void __init hi3xxx_clkmux_setup(struct device_node *np)
+{
+	clkmux_setup(np, 0);
+}
+CLK_OF_DECLARE(hi3xxx_mux, "hisilicon,clk-mux", hi3xxx_clkmux_setup)
+
+static void __init hs_clkgate_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names, *name;
+	unsigned long flags = 0;
+	u32 data[2];
+	void __iomem *base;
+
+	base = hi3xxx_init_clocks(np);
+	if (!base)
+		return;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,clkgate",
+				       &data[0], 2))
+		return;
+	if (of_property_read_bool(np, "hisilicon,clkgate-inverted"))
+		flags = CLK_GATE_SET_TO_DISABLE;
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		return;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	clk = clk_register_gate(NULL, clk_name, parent_names[0], 0,
+				base + data[0], (u8)data[1], flags,
+				&hi3xxx_clk_lock);
+	if (IS_ERR(clk))
+		goto err;
+	if (!of_property_read_string(np, "clock-names", &name))
+		clk_register_clkdev(clk, name, NULL);
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err:
+	kfree(parent_names);
+}
+CLK_OF_DECLARE(hs_gate, "hisilicon,clk-gate", hs_clkgate_setup)
+
+void __init hi3620_clkdiv_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	struct clk_div_table *table;
+	unsigned int table_num;
+	int i;
+	u32 data[2];
+	u8 shift, width;
+	const char *propname = "hisilicon,clkdiv-table";
+	const char *cellname = "#hisilicon,clkdiv-table-cells";
+	struct of_phandle_args div_table;
+	void __iomem *reg, *base;
+
+	base = hi3xxx_init_clocks(np);
+	if (!base)
+		return;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,clkdiv",
+				       &data[0], 2))
+		return;
+
+	/*process the div_table*/
+	for (i = 0; ; i++) {
+		if (of_parse_phandle_with_args(np, propname, cellname,
+					       i, &div_table))
+			break;
+	}
+
+	/*table ends with <0, 0>, so plus one to table_num*/
+	table_num = i + 1;
+
+	table = kzalloc(sizeof(struct clk_div_table) * table_num, GFP_KERNEL);
+	if (!table)
+		return ;
+
+	for (i = 0; ; i++) {
+		if (of_parse_phandle_with_args(np, propname, cellname,
+					       i, &div_table))
+			break;
+
+		table[i].val = div_table.args[0];
+		table[i].div = div_table.args[1];
+	}
+
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		goto err_par;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+	reg = base + data[0];
+	shift = ffs(data[1]) - 1;
+	width = fls(data[1]) - ffs(data[1]) + 1;
+	clk = clk_register_divider_table(NULL, clk_name, parent_names[0], 0,
+					 reg, shift, width,
+					 CLK_DIVIDER_HIWORD_MASK,
+					 table, &hi3xxx_clk_lock);
+	if (IS_ERR(clk))
+		goto err_clk;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err_clk:
+	kfree(parent_names);
+err_par:
+	kfree(table);
+}
+CLK_OF_DECLARE(hi3620_div, "hisilicon,hi3620-clk-div", hi3620_clkdiv_setup)
-- 
1.8.1.2

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

* [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc
  2013-06-17  8:56 [PATCH v5 0/4] support Hisilicon SoC Haojian Zhuang
  2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
@ 2013-06-17  8:56 ` Haojian Zhuang
  2013-06-17 21:51   ` Olof Johansson
  2013-06-17  8:56 ` [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree Haojian Zhuang
  2013-06-17  8:56 ` [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 " Haojian Zhuang
  3 siblings, 1 reply; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Support UART0 debug ll on hisilicon Hi3620 SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/Kconfig.debug             | 15 +++++++++++++++
 arch/arm/include/debug/hisilicon.S | 30 ++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 arch/arm/include/debug/hisilicon.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1d41908..7396572 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -251,6 +251,20 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX6Q/DL.
 
+	config DEBUG_HI3620_UART
+		bool "Hisilicon HI3620 Debug UART"
+		depends on ARCH_HI3xxx
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on HI3620 UART.
+
+	config DEBUG_HI3716_UART
+		bool "Hisilicon Hi3716 Debug UART"
+		depends on ARCH_HI3xxx
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on HI3716 UART.
+
 	config DEBUG_MMP_UART2
 		bool "Kernel low-level debugging message via MMP UART2"
 		depends on ARCH_MMP
@@ -623,6 +637,7 @@ config DEBUG_LL_INCLUDE
 	default "debug/cns3xxx.S" if DEBUG_CNS3XXX
 	default "debug/exynos.S" if DEBUG_EXYNOS_UART
 	default "debug/highbank.S" if DEBUG_HIGHBANK_UART
+	default "debug/hisilicon.S" if DEBUG_HI3620_UART || DEBUG_HI3716_UART
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
diff --git a/arch/arm/include/debug/hisilicon.S b/arch/arm/include/debug/hisilicon.S
new file mode 100644
index 0000000..47ad019
--- /dev/null
+++ b/arch/arm/include/debug/hisilicon.S
@@ -0,0 +1,30 @@
+/*
+ * Early serial output macro for Hisilicon SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Technologies Co., Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_DEBUG_HI3620_UART)
+#define HS_UART_PHYS_BASE	0xfcb00000
+#define HS_UART_VIRT_BASE	0xfeb00000
+#elif defined(CONFIG_DEBUG_HI3716_UART)
+#define HS_UART_PHYS_BASE	0xf8b00000
+#define HS_UART_VIRT_BASE	0xfeb00000
+#endif
+
+#if defined(CONFIG_DEBUG_HI3620_UART) || defined(CONFIG_DEBUG_HI3716_UART)
+		.macro	addruart,rp,rv,tmp
+		ldr	\rp, =HS_UART_PHYS_BASE
+		ldr	\rv, =HS_UART_VIRT_BASE
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
+
+#endif
-- 
1.8.1.2

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

* [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree
  2013-06-17  8:56 [PATCH v5 0/4] support Hisilicon SoC Haojian Zhuang
  2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
  2013-06-17  8:56 ` [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
@ 2013-06-17  8:56 ` Haojian Zhuang
  2013-06-17 21:51   ` Olof Johansson
  2013-06-17  8:56 ` [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 " Haojian Zhuang
  3 siblings, 1 reply; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Add board support with device tree for Hisilicon Hi36xx/Hi37xx platform.

Changelog:
v3:
1. Remove .map_io() in DT machine descriptor. Since debug_ll_io_init()
is called by default.
2. Remove .init_machine() in DT machine descriptor. Since
of_platform_populate() is called by default in DT mode.

v2:
1. Remove .init_irq() in DT machine descriptor. Since irqchip_init()
is called by default in DT mode.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../bindings/arm/hisilicon/hisilicon.txt           | 10 ++++++
 arch/arm/Kconfig                                   |  2 ++
 arch/arm/Makefile                                  |  1 +
 arch/arm/mach-hi3xxx/Kconfig                       | 13 ++++++++
 arch/arm/mach-hi3xxx/Makefile                      |  5 +++
 arch/arm/mach-hi3xxx/hi3xxx.c                      | 36 ++++++++++++++++++++++
 6 files changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
 create mode 100644 arch/arm/mach-hi3xxx/Kconfig
 create mode 100644 arch/arm/mach-hi3xxx/Makefile
 create mode 100644 arch/arm/mach-hi3xxx/hi3xxx.c

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
new file mode 100644
index 0000000..3be60c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -0,0 +1,10 @@
+Hisilicon Platforms Device Tree Bindings
+----------------------------------------------------
+
+Hi3716 Development Board
+Required root node properties:
+	- compatible = "hisilicon,hi3716-dkb";
+
+Hi4511 Board
+Required root node properties:
+	- compatible = "hisilicon,hi3620-hi4511";
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993c..acd2358 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -936,6 +936,8 @@ source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-gemini/Kconfig"
 
+source "arch/arm/mach-hi3xxx/Kconfig"
+
 source "arch/arm/mach-highbank/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1ba358b..748a9ca 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -147,6 +147,7 @@ machine-$(CONFIG_ARCH_DOVE)		+= dove
 machine-$(CONFIG_ARCH_EBSA110)		+= ebsa110
 machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
+machine-$(CONFIG_ARCH_HI3xxx)		+= hi3xxx
 machine-$(CONFIG_ARCH_HIGHBANK)		+= highbank
 machine-$(CONFIG_ARCH_INTEGRATOR)	+= integrator
 machine-$(CONFIG_ARCH_IOP13XX)		+= iop13xx
diff --git a/arch/arm/mach-hi3xxx/Kconfig b/arch/arm/mach-hi3xxx/Kconfig
new file mode 100644
index 0000000..a991dee
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/Kconfig
@@ -0,0 +1,13 @@
+config ARCH_HI3xxx
+	bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select CACHE_L2X0
+	select CACHE_PL310
+	select CLKSRC_OF
+	select PINCTRL
+	select PINCTRL_SINGLE
+	select SERIAL_AMBA_PL011
+	select SERIAL_AMBA_PL011_CONSOLE
+	help
+	  Support for Hisilicon Hi36xx/Hi37xx processor family
diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
new file mode 100644
index 0000000..d68ebb3
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Hisilicon Hi36xx/Hi37xx processors line
+#
+
+obj-y	+= hi3xxx.o
diff --git a/arch/arm/mach-hi3xxx/hi3xxx.c b/arch/arm/mach-hi3xxx/hi3xxx.c
new file mode 100644
index 0000000..e7c54bc
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/hi3xxx.c
@@ -0,0 +1,36 @@
+/*
+ * (Hisilicon's Hi36xx/Hi37xx SoC based) flattened device tree enabled machine
+ *
+ * Copyright (c) 2012-2013 Hisilicon Ltd.
+ * Copyright (c) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static void __init hi3xxx_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static const char *hs_compat[] __initdata = {
+	"hisilicon,hi3620-hi4511",
+	NULL,
+};
+
+DT_MACHINE_START(HI3xxx, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)")
+	.init_time	= hi3xxx_timer_init,
+	.dt_compat	= hs_compat,
+MACHINE_END
-- 
1.8.1.2

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

* [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 with device tree
  2013-06-17  8:56 [PATCH v5 0/4] support Hisilicon SoC Haojian Zhuang
                   ` (2 preceding siblings ...)
  2013-06-17  8:56 ` [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree Haojian Zhuang
@ 2013-06-17  8:56 ` Haojian Zhuang
  2013-06-17 17:41   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-06-17 22:05   ` Olof Johansson
  3 siblings, 2 replies; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Enable Hisilicon Hi4511 development platform with device tree support.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/boot/dts/Makefile          |    1 +
 arch/arm/boot/dts/hi3620.dtsi       | 1147 +++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/hi4511.dts        |  648 ++++++++++++++++++++
 arch/arm/configs/multi_v7_defconfig |    1 +
 4 files changed, 1797 insertions(+)
 create mode 100644 arch/arm/boot/dts/hi3620.dtsi
 create mode 100644 arch/arm/boot/dts/hi4511.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f0895c5..216f983 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -58,6 +58,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
 	exynos5250-smdk5250.dtb \
 	exynos5250-snow.dtb \
 	exynos5440-ssdk5440.dtb
+dtb-$(CONFIG_ARCH_HI3xxx) += hi4511.dtb
 dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
 	ecx-2000.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 0000000..1f0a4aa
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,1147 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	osc32k: osc at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "osc32khz";
+	};
+	osc26m: osc at 1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "osc26mhz";
+	};
+	pclk: clk at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "apb_pclk";
+	};
+	pll_arm0: clk at 1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1600000000>;
+		clock-output-names = "armpll0";
+	};
+	pll_arm1: clk at 2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1600000000>;
+		clock-output-names = "armpll1";
+	};
+	pll_peri: clk at 3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1440000000>;
+		clock-output-names = "armpll2";
+	};
+	pll_usb: clk at 4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1440000000>;
+		clock-output-names = "armpll3";
+	};
+	pll_hdmi: clk at 5 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1188000000>;
+		clock-output-names = "armpll4";
+	};
+	pll_gpu: clk at 6 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1300000000>;
+		clock-output-names = "armpll5";
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		pmctrl: pmctrl at fca08000 {
+			compatible = "hisilicon,pmctrl";
+			reg = <0xfca08000 0x1000>;
+		};
+
+		sctrl: sctrl at fc802000 {
+			compatible = "hisilicon,sctrl";
+			reg = <0xfc802000 0x1000>;
+
+			uart0_mux: uart0_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "uart0_mux";
+				/* reg_offset, mask bits */
+				hisilicon,clkmux-reg = <0x100 0x80>;
+				/* each item value */
+				hisilicon,clkmux-table = <0 0x80>;
+			};
+			uart1_mux: uart1_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "uart1_mux";
+				hisilicon,clkmux-reg = <0x100 0x100>;
+				hisilicon,clkmux-table = <0x0 0x100>;
+			};
+			uart2_mux: uart2_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "uart2_mux";
+				hisilicon,clkmux-reg = <0x100 0x200>;
+				hisilicon,clkmux-table = <0 0x200>;
+			};
+			uart3_mux: uart3_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "uart3_mux";
+				hisilicon,clkmux-reg = <0x100 0x400>;
+				hisilicon,clkmux-table = <0 0x400>;
+			};
+			uart4_mux: uart4_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "uart4_mux";
+				hisilicon,clkmux-reg = <0x100 0x800>;
+				hisilicon,clkmux-table = <0 0x800>;
+			};
+			rclk_cfgaxi: rclk_cfgaxi {
+				compatible = "fixed-factor-clock";
+				#clock-cells = <0>;
+				clocks = <&pll_peri>;
+				clock-output-names = "rclk_cfgaxi";
+				clock-mult = <1>;
+				clock-div = <30>;
+			};
+			spi0_mux: spi0_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &rclk_cfgaxi>;
+				clock-output-names = "spi0_mux";
+				hisilicon,clkmux-reg = <0x100 0x1000>;
+				hisilicon,clkmux-table = <0 0x1000>;
+			};
+			spi1_mux: spi1_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &rclk_cfgaxi>;
+				clock-output-names = "spi1_mux";
+				hisilicon,clkmux-reg = <0x100 0x2000>;
+				hisilicon,clkmux-table = <0 0x2000>;
+			};
+			spi2_mux: spi2_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &rclk_cfgaxi>;
+				clock-output-names = "spi2_mux";
+				hisilicon,clkmux-reg = <0x100 0x4000>;
+				hisilicon,clkmux-table = <0 0x4000>;
+			};
+			pwm0_mux: pwm0_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &osc26m>;
+				clock-output-names = "pwm0_mux";
+				hisilicon,clkmux-reg = <0x104 0x400>;
+				hisilicon,clkmux-table = <0 0x400>;
+			};
+			pwm1_mux: pwm1_mux {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &osc26m>;
+				clock-output-names = "pwm1_mux";
+				hisilicon,clkmux-reg = <0x104 0x800>;
+				hisilicon,clkmux-table = <0 0x800>;
+			};
+			timer0_mux: timer0_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk01>;
+				clock-output-names = "timer0_mux";
+				hisilicon,clkmux-reg = <0 0x8000>;
+				hisilicon,clkmux-table = <0 0x8000>;
+			};
+			timer1_mux: timer1_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk01>;
+				clock-output-names = "timer1_mux";
+				hisilicon,clkmux-reg = <0 0x20000>;
+				hisilicon,clkmux-table = <0 0x20000>;
+			};
+			timer2_mux: timer2_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk23>;
+				clock-output-names = "timer2_mux";
+				hisilicon,clkmux-reg = <0 0x80000>;
+				hisilicon,clkmux-table = <0 0x80000>;
+			};
+			timer3_mux: timer3_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk23>;
+				clock-output-names = "timer3_mux";
+				hisilicon,clkmux-reg = <0 0x200000>;
+				hisilicon,clkmux-table = <0 0x200000>;
+			};
+			timer4_mux: timer4_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk45>;
+				clock-output-names = "timer4_mux";
+				hisilicon,clkmux-reg = <0x18 0x1>;
+				hisilicon,clkmux-table = <0 0x1>;
+			};
+			timer5_mux: timer5_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk45>;
+				clock-output-names = "timer5_mux";
+				hisilicon,clkmux-reg = <0x18 0x4>;
+				hisilicon,clkmux-table = <0 0x4>;
+			};
+			timer6_mux: timer6_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk67>;
+				clock-output-names = "timer6_mux";
+				hisilicon,clkmux-reg = <0x18 0x10>;
+				hisilicon,clkmux-table = <0 0x10>;
+			};
+			timer7_mux: timer7_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk67>;
+				clock-output-names = "timer7_mux";
+				hisilicon,clkmux-reg = <0x18 0x40>;
+				hisilicon,clkmux-table = <0 0x40>;
+			};
+			timer8_mux: timer8_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk89>;
+				clock-output-names = "timer8_mux";
+				hisilicon,clkmux-reg = <0x18 0x100>;
+				hisilicon,clkmux-table = <0 0x100>;
+			};
+			timer9_mux: timer9_mux {
+				compatible = "hisilicon,clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk89>;
+				clock-output-names = "timer9_mux";
+				hisilicon,clkmux-reg = <0x18 0x400>;
+				hisilicon,clkmux-table = <0 0x400>;
+			};
+			rclk_shareAXI: rclk_shareAXI {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&pll_usb &pll_peri>;
+				clock-output-names = "rclk_shareAXI";
+				hisilicon,clkmux-reg = <0x100 0x8000>;
+				hisilicon,clkmux-table = <0 0x8000>;
+			};
+			uartclk0: uartclk0 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&uart0_mux>;
+				clock-output-names = "uartclk0";
+				hisilicon,hi3620-clkreset = <0x98 0x10000>;
+				hisilicon,hi3620-clkgate = <0x40 0x10000>;
+			};
+			uartclk1: uartclk1 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&uart1_mux>;
+				clock-output-names = "uartclk1";
+				hisilicon,hi3620-clkreset = <0x98 0x20000>;
+				hisilicon,hi3620-clkgate = <0x40 0x20000>;
+			};
+			uartclk2: uartclk2 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&uart2_mux>;
+				clock-output-names = "uartclk2";
+				hisilicon,hi3620-clkreset = <0x98 0x40000>;
+				hisilicon,hi3620-clkgate = <0x40 0x40000>;
+			};
+			uartclk3: uartclk3 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&uart3_mux>;
+				clock-output-names = "uartclk3";
+				hisilicon,hi3620-clkreset = <0x98 0x80000>;
+				hisilicon,hi3620-clkgate = <0x40 0x80000>;
+			};
+			uartclk4: uartclk4 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&uart4_mux>;
+				clock-output-names = "uartclk4";
+				hisilicon,hi3620-clkreset = <0x98 0x100000>;
+				hisilicon,hi3620-clkgate = <0x40 0x100000>;
+			};
+			gpioclk0: gpioclk0 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk0";
+				hisilicon,hi3620-clkreset = <0x80 0x100>;
+				hisilicon,hi3620-clkgate = <0x20 0x100>;
+			};
+			gpioclk1: gpioclk1 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk1";
+				hisilicon,hi3620-clkreset = <0x80 0x200>;
+				hisilicon,hi3620-clkgate = <0x20 0x200>;
+			};
+			gpioclk2: gpioclk2 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk2";
+				hisilicon,hi3620-clkreset = <0x80 0x400>;
+				hisilicon,hi3620-clkgate = <0x20 0x400>;
+			};
+			gpioclk3: gpioclk3 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk3";
+				hisilicon,hi3620-clkreset = <0x80 0x800>;
+				hisilicon,hi3620-clkgate = <0x20 0x800>;
+			};
+			gpioclk4: gpioclk4 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk4";
+				hisilicon,hi3620-clkreset = <0x80 0x1000>;
+				hisilicon,hi3620-clkgate = <0x20 0x1000>;
+			};
+			gpioclk5: gpioclk5 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk5";
+				hisilicon,hi3620-clkreset = <0x80 0x2000>;
+				hisilicon,hi3620-clkgate = <0x20 0x2000>;
+			};
+			gpioclk6: gpioclk6 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk6";
+				hisilicon,hi3620-clkreset = <0x80 0x4000>;
+				hisilicon,hi3620-clkgate = <0x20 0x4000>;
+			};
+			gpioclk7: gpioclk7 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk7";
+				hisilicon,hi3620-clkreset = <0x80 0x8000>;
+				hisilicon,hi3620-clkgate = <0x20 0x8000>;
+			};
+			gpioclk8: gpioclk8 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk8";
+				hisilicon,hi3620-clkreset = <0x80 0x10000>;
+				hisilicon,hi3620-clkgate = <0x20 0x10000>;
+			};
+			gpioclk9: gpioclk9 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk9";
+				hisilicon,hi3620-clkreset = <0x80 0x20000>;
+				hisilicon,hi3620-clkgate = <0x20 0x20000>;
+			};
+			gpioclk10: gpioclk10 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk10";
+				hisilicon,hi3620-clkreset = <0x80 0x40000>;
+				hisilicon,hi3620-clkgate = <0x20 0x40000>;
+			};
+			gpioclk11: gpioclk11 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk11";
+				hisilicon,hi3620-clkreset = <0x80 0x80000>;
+				hisilicon,hi3620-clkgate = <0x20 0x80000>;
+			};
+			gpioclk12: gpioclk12 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk12";
+				hisilicon,hi3620-clkreset = <0x80 0x100000>;
+				hisilicon,hi3620-clkgate = <0x20 0x100000>;
+			};
+			gpioclk13: gpioclk13 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk13";
+				hisilicon,hi3620-clkreset = <0x80 0x200000>;
+				hisilicon,hi3620-clkgate = <0x20 0x200000>;
+			};
+			gpioclk14: gpioclk14 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk14";
+				hisilicon,hi3620-clkreset = <0x80 0x400000>;
+				hisilicon,hi3620-clkgate = <0x20 0x400000>;
+			};
+			gpioclk15: gpioclk15 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk15";
+				hisilicon,hi3620-clkreset = <0x80 0x800000>;
+				hisilicon,hi3620-clkgate = <0x20 0x800000>;
+			};
+			gpioclk16: gpioclk16 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk16";
+				hisilicon,hi3620-clkreset = <0x80 0x1000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x1000000>;
+			};
+			gpioclk17: gpioclk17 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk17";
+				hisilicon,hi3620-clkreset = <0x80 0x2000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x2000000>;
+			};
+			gpioclk18: gpioclk18 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk18";
+				hisilicon,hi3620-clkreset = <0x80 0x4000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x4000000>;
+			};
+			gpioclk19: gpioclk19 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk19";
+				hisilicon,hi3620-clkreset = <0x80 0x8000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x8000000>;
+			};
+			gpioclk20: gpioclk20 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk20";
+				hisilicon,hi3620-clkreset = <0x80 0x10000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x10000000>;
+			};
+			gpioclk21: gpioclk21 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk21";
+				hisilicon,hi3620-clkreset = <0x80 0x20000000>;
+				hisilicon,hi3620-clkgate = <0x20 0x20000000>;
+			};
+			spiclk0: spiclk0 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&spi0_mux>;
+				clock-output-names = "spiclk0";
+				hisilicon,hi3620-clkreset = <0x98 0x200000>;
+				hisilicon,hi3620-clkgate = <0x40 0x200000>;
+			};
+			spiclk1: spiclk1 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&spi1_mux>;
+				clock-output-names = "spiclk1";
+				hisilicon,hi3620-clkreset = <0x98 0x400000>;
+				hisilicon,hi3620-clkgate = <0x40 0x400000>;
+			};
+			spiclk2: spiclk2 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&spi2_mux>;
+				clock-output-names = "spiclk2";
+				hisilicon,hi3620-clkreset = <0x98 0x800000>;
+				hisilicon,hi3620-clkgate = <0x40 0x800000>;
+			};
+			pwmclk0: pwmclk0 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pwm0_mux>;
+				clock-output-names = "pwmclk0";
+				hisilicon,hi3620-clkreset = <0x98 0x80>;
+				hisilicon,hi3620-clkgate = <0x40 0x80>;
+			};
+			pwmclk1: pwmclk1 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pwm1_mux>;
+				clock-output-names = "pwmclk1";
+				hisilicon,hi3620-clkreset = <0x98 0x100>;
+				hisilicon,hi3620-clkgate = <0x40 0x100>;
+			};
+			timerclk01: timerclk01 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "timerclk01";
+				hisilicon,hi3620-clkreset = <0x80 0x1>;
+				hisilicon,hi3620-clkgate = <0x20 0x3>;
+			};
+			timerclk23: timerclk23 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "timerclk23";
+				hisilicon,hi3620-clkreset = <0x80 0x2>;
+				hisilicon,hi3620-clkgate = <0x20 0xc>;
+			};
+			timerclk45: timerclk45 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "timerclk45";
+				hisilicon,hi3620-clkreset = <0x98 0x8>;
+				hisilicon,hi3620-clkgate = <0x40 0x8>;
+			};
+			timerclk67: timerclk67 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "timerclk67";
+				hisilicon,hi3620-clkreset = <0x98 0x10>;
+				hisilicon,hi3620-clkgate = <0x40 0x10>;
+			};
+			timerclk89: timerclk89 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "timerclk89";
+				hisilicon,hi3620-clkreset = <0x98 0x20>;
+				hisilicon,hi3620-clkgate = <0x40 0x20>;
+			};
+			timclk0: timclk0 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer0_mux>;
+				clock-output-names = "timclk0";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 16>;
+			};
+			timclk1: timclk1 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer1_mux>;
+				clock-output-names = "timclk1";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 18>;
+			};
+			timclk2: timclk2 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer2_mux>;
+				clock-output-names = "timclk2";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 20>;
+			};
+			timclk3: timclk3 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer3_mux>;
+				clock-output-names = "timclk3";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 22>;
+			};
+			timclk4: timclk4 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer4_mux>;
+				clock-output-names = "timclk4";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 0>;
+			};
+			timclk5: timclk5 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer5_mux>;
+				clock-output-names = "timclk5";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 2>;
+			};
+			timclk6: timclk6 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer6_mux>;
+				clock-output-names = "timclk6";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 4>;
+			};
+			timclk7: timclk7 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer7_mux>;
+				clock-output-names = "timclk7";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 6>;
+			};
+			timclk8: timclk8 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer8_mux>;
+				clock-output-names = "timclk8";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 8>;
+			};
+			timclk9: timclk9 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&timer9_mux>;
+				clock-output-names = "timclk9";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0x18 10>;
+			};
+			dtable: dtable {
+				#hisilicon,clkdiv-table-cells = <2>;
+			};
+			div_shareaxi: div_shareaxi {
+				compatible = "hisilicon,hi3620-clk-div";
+				#clock-cells = <0>;
+				clocks = <&rclk_shareAXI>;
+				clock-output-names = "shareAXI_div";
+				hisilicon,clkdiv-table = <
+					&dtable 0 1 &dtable 1 2 &dtable 2 3 &dtable 3 4
+					&dtable 4 5 &dtable 5 6 &dtable 6 7 &dtable 7 8
+					&dtable 8 9 &dtable 9 10 &dtable 10 11 &dtable 11 12
+					&dtable 12 13 &dtable 13 14 &dtable 14 15 &dtable 15 16
+					&dtable 16 17 &dtable 17 18 &dtable 18 19 &dtable 19 20
+					&dtable 20 21 &dtable 21 22 &dtable 22 23 &dtable 23 24
+					&dtable 24 25 &dtable 25 26 &dtable 26 27 &dtable 27 28
+					&dtable 28 29 &dtable 29 30 &dtable 30 31 &dtable 31 32>;
+				/* divider register offset, mask */
+				hisilicon,clkdiv = <0x100 0x1f>;
+			};
+			div_cfgaxi: div_cfgaxi {
+				compatible = "hisilicon,hi3620-clk-div";
+				#clock-cells = <0>;
+				clocks = <&div_shareaxi>;
+				clock-output-names = "cfgAXI_div";
+				hisilicon,clkdiv-table = <&dtable 0x01 2>;
+				hisilicon,clkdiv = <0x100 0x60>;
+			};
+		};
+
+		l2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0xfc10000 0x100000>;
+			interrupts = <0 15 4>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		intc: interrupt-controller at fc001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			/* gic dist base, gic cpu base */
+			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
+		};
+
+		timer0: timer at fc800000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc800000 0x1000>;
+			/* timer00 & timer01 */
+			interrupts = <0 0 4>, <0 1 4>;
+			clocks = <&timclk0 &timclk1>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		timer1: timer at fc801000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc801000 0x1000>;
+			/* timer10 & timer11 */
+			interrupts = <0 2 4>, <0 3 4>;
+			clocks = <&timclk2 &timclk3>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		timer2: timer at fca01000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca01000 0x1000>;
+			/* timer20 & timer21 */
+			interrupts = <0 4 4>, <0 5 4>;
+			clocks = <&timclk4 &timclk5>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		timer3: timer at fca02000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca02000 0x1000>;
+			/* timer30 & timer31 */
+			interrupts = <0 6 4>, <0 7 4>;
+			clocks = <&timclk6 &timclk7>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		timer4: timer at fca03000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca03000 0x1000>;
+			/* timer40 & timer41 */
+			interrupts = <0 96 4>, <0 97 4>;
+			clocks = <&timclk8 &timclk9>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart0: uart at fcb00000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb00000 0x1000>;
+			interrupts = <0 20 4>;
+			clocks = <&uartclk0>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart1: uart at fcb01000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb01000 0x1000>;
+			interrupts = <0 21 4>;
+			clocks = <&uartclk1>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart2: uart at fcb02000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb02000 0x1000>;
+			interrupts = <0 22 4>;
+			clocks = <&uartclk2>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart3: uart at fcb03000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb03000 0x1000>;
+			interrupts = <0 23 4>;
+			clocks = <&uartclk3>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart4: uart at fcb04000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb04000 0x1000>;
+			interrupts = <0 24 4>;
+			clocks = <&uartclk4>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		gpio0: gpio at fc806000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc806000 0x1000>;
+			interrupts = <0 64 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 2 0 1 &pmx0 3 0 1 &pmx0 4 0 1
+					&pmx0 5 0 1 &pmx0 6 1 1 &pmx0 7 2 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk0>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio1: gpio at fc807000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc807000 0x1000>;
+			interrupts = <0 65 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+					&pmx0 3 3 1 &pmx0 4 3 1 &pmx0 5 4 1
+					&pmx0 6 5 1 &pmx0 7 6 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk1>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio2: gpio at fc808000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc808000 0x1000>;
+			interrupts = <0 66 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 7 1 &pmx0 1 8 1 &pmx0 2 9 1
+					&pmx0 3 10 1 &pmx0 4 3 1 &pmx0 5 3 1
+					&pmx0 6 3 1 &pmx0 7 3 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk2>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio3: gpio at fc809000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc809000 0x1000>;
+			interrupts = <0 67 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+					&pmx0 3 3 1 &pmx0 4 11 1 &pmx0 5 11 1
+					&pmx0 6 11 1 &pmx0 7 11 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk3>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio4: gpio at fc80a000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80a000 0x1000>;
+			interrupts = <0 68 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 11 1 &pmx0 1 11 1 &pmx0 2 11 1
+					&pmx0 3 11 1 &pmx0 4 12 1 &pmx0 5 12 1
+					&pmx0 6 13 1 &pmx0 7 13 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk4>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio5: gpio at fc80b000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80b000 0x1000>;
+			interrupts = <0 69 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 14 1 &pmx0 1 15 1 &pmx0 2 16 1
+					&pmx0 3 16 1 &pmx0 4 16 1 &pmx0 5 16 1
+					&pmx0 6 16 1 &pmx0 7 16 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk5>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio6: gpio at fc80c000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80c000 0x1000>;
+			interrupts = <0 70 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 16 1 &pmx0 1 16 1 &pmx0 2 17 1
+					&pmx0 3 17 1 &pmx0 4 18 1 &pmx0 5 18 1
+					&pmx0 6 18 1 &pmx0 7 19 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk6>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio7: gpio at fc80d000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80d000 0x1000>;
+			interrupts = <0 71 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 19 1 &pmx0 1 20 1 &pmx0 2 21 1
+					&pmx0 3 22 1 &pmx0 4 23 1 &pmx0 5 24 1
+					&pmx0 6 25 1 &pmx0 7 26 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk7>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio8: gpio at fc80e000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80e000 0x1000>;
+			interrupts = <0 72 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 27 1 &pmx0 1 28 1 &pmx0 2 29 1
+					&pmx0 3 30 1 &pmx0 4 31 1 &pmx0 5 32 1
+					&pmx0 6 33 1 &pmx0 7 34 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk8>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio9: gpio at fc80f000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc80f000 0x1000>;
+			interrupts = <0 73 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 35 1 &pmx0 1 36 1 &pmx0 2 37 1
+					&pmx0 3 38 1 &pmx0 4 39 1 &pmx0 5 40 1
+					&pmx0 6 41 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk9>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio10: gpio at fc810000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc810000 0x1000>;
+			interrupts = <0 74 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 2 43 1 &pmx0 3 44 1 &pmx0 4 45 1
+					&pmx0 5 45 1 &pmx0 6 46 1 &pmx0 7 46 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk10>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio11: gpio at fc811000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc811000 0x1000>;
+			interrupts = <0 75 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 47 1 &pmx0 1 47 1 &pmx0 2 47 1
+					&pmx0 3 47 1 &pmx0 4 47 1 &pmx0 5 48 1
+					&pmx0 6 49 1 &pmx0 7 49 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk11>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio12: gpio at fc812000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc812000 0x1000>;
+			interrupts = <0 76 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 49 1 &pmx0 1 50 1 &pmx0 2 49 1
+					&pmx0 3 49 1 &pmx0 4 51 1 &pmx0 5 51 1
+					&pmx0 6 51 1 &pmx0 7 52 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk12>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio13: gpio at fc813000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc813000 0x1000>;
+			interrupts = <0 77 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 51 1 &pmx0 1 51 1 &pmx0 2 53 1
+					&pmx0 3 53 1 &pmx0 4 53 1 &pmx0 5 54 1
+					&pmx0 6 55 1 &pmx0 7 56 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk13>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio14: gpio at fc814000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc814000 0x1000>;
+			interrupts = <0 78 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 57 1 &pmx0 1 97 1 &pmx0 2 97 1
+					&pmx0 3 58 1 &pmx0 4 59 1 &pmx0 5 60 1
+					&pmx0 6 60 1 &pmx0 7 61 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk14>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio15: gpio at fc815000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc815000 0x1000>;
+			interrupts = <0 79 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 61 1 &pmx0 1 62 1 &pmx0 2 62 1
+					&pmx0 3 63 1 &pmx0 4 63 1 &pmx0 5 64 1
+					&pmx0 6 64 1 &pmx0 7 65 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk15>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio16: gpio at fc816000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc816000 0x1000>;
+			interrupts = <0 80 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 66 1 &pmx0 1 67 1 &pmx0 2 68 1
+					&pmx0 3 69 1 &pmx0 4 70 1 &pmx0 5 71 1
+					&pmx0 6 72 1 &pmx0 7 73 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk16>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio17: gpio at fc817000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc817000 0x1000>;
+			interrupts = <0 81 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 74 1 &pmx0 1 75 1 &pmx0 2 76 1
+					&pmx0 3 77 1 &pmx0 4 78 1 &pmx0 5 79 1
+					&pmx0 6 80 1 &pmx0 7 81 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk17>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio18: gpio at fc818000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc818000 0x1000>;
+			interrupts = <0 82 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 82 1 &pmx0 1 83 1 &pmx0 2 83 1
+					&pmx0 3 84 1 &pmx0 4 84 1 &pmx0 5 85 1
+					&pmx0 6 86 1 &pmx0 7 87 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk18>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio19: gpio at fc819000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc819000 0x1000>;
+			interrupts = <0 83 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 87 1 &pmx0 1 87 1 &pmx0 2 88 1
+					&pmx0 3 88 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk19>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio20: gpio at fc81a000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc81a000 0x1000>;
+			interrupts = <0 84 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1
+					&pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk20>;
+			clock-names = "apb_pclk";
+		};
+
+		gpio21: gpio at fc81b000 {
+			compatible = "arm,pl061", "arm,primecell";
+			reg = <0xfc81b000 0x1000>;
+			interrupts = <0 85 0x4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <	&pmx0 3 94 1 &pmx0 7 96 1>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&gpioclk21>;
+			clock-names = "apb_pclk";
+		};
+
+		pmx0: pinmux at fc803000 {
+			compatible = "pinctrl-single";
+			reg = <0xfc803000 0x188>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			#gpio-range-cells = <3>;
+			ranges;
+
+			pinctrl-single,register-width = <32>;
+			pinctrl-single,function-mask = <7>;
+			/* pin base, nr pins & gpio function */
+			pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
+						&range 12 1 0 &range 13 29 1
+						&range 43 1 0 &range 44 49 1
+						&range 94 1 1 &range 96 2 1>;
+
+			range: gpio-range {
+				#pinctrl-single,gpio-range-cells = <3>;
+			};
+		};
+
+		pmx1: pinmux at fc803800 {
+			compatible = "pinconf-single";
+			reg = <0xfc803800 0x2dc>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			pinctrl-single,register-width = <32>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hi4511.dts b/arch/arm/boot/dts/hi4511.dts
new file mode 100644
index 0000000..66ac03a
--- /dev/null
+++ b/arch/arm/boot/dts/hi4511.dts
@@ -0,0 +1,648 @@
+/*
+ *  Copyright (C) 2012-2013 Linaro Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "hi3620.dtsi"
+
+/ {
+	model = "Hisilicon Hi4511 Development Board";
+	compatible = "hisilicon,hi3620-hi4511";
+
+	chosen {
+		bootargs = "console=ttyAMA0,115200 root=/dev/ram0";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
+
+	amba {
+		timer0: timer at fc800000 {
+			status = "ok";
+		};
+
+		uart0: uart at fcb00000 {	/* console */
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>;
+			pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>;
+			status = "ok";
+		};
+
+		uart1: uart at fcb01000 { /* modem */
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>;
+			pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>;
+			status = "ok";
+		};
+
+		uart2: uart at fcb02000 { /* audience */
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>;
+			pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>;
+			status = "ok";
+		};
+
+		uart3: uart at fcb03000 {
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
+			pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>;
+			status = "ok";
+		};
+
+		uart4: uart at fcb04000 {
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>;
+			pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>;
+			status = "ok";
+		};
+
+		pmx0: pinmux at fc803000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&board_pmx_pins>;
+
+			board_pmx_pins: board_pmx_pins {
+				pinctrl-single,pins = <
+					0x008 0x0	/* GPIO -- eFUSE_DOUT */
+					0x100 0x0	/* USIM_CLK & USIM_DATA (IOMG63) */
+				>;
+			};
+			uart0_pmx_func: uart0_pmx_func {
+				pinctrl-single,pins = <
+					0x0f0 0x0
+					0x0f4 0x0	/* UART0_RX & UART0_TX */
+				>;
+			};
+			uart0_pmx_idle: uart0_pmx_idle {
+				pinctrl-single,pins = <
+					/*0x0f0 0x1*/	/* UART0_CTS & UART0_RTS */
+					0x0f4 0x1	/* UART0_RX & UART0_TX */
+				>;
+			};
+			uart1_pmx_func: uart1_pmx_func {
+				pinctrl-single,pins = <
+					0x0f8 0x0	/* UART1_CTS & UART1_RTS (IOMG61) */
+					0x0fc 0x0	/* UART1_RX & UART1_TX (IOMG62) */
+				>;
+			};
+			uart1_pmx_idle: uart1_pmx_idle {
+				pinctrl-single,pins = <
+					0x0f8 0x1	/* GPIO (IOMG61) */
+					0x0fc 0x1	/* GPIO (IOMG62) */
+				>;
+			};
+			uart2_pmx_func: uart2_pmx_func {
+				pinctrl-single,pins = <
+					0x104 0x2	/* UART2_RXD (IOMG96) */
+					0x108 0x2	/* UART2_TXD (IOMG64) */
+				>;
+			};
+			uart2_pmx_idle: uart2_pmx_idle {
+				pinctrl-single,pins = <
+					0x104 0x1	/* GPIO (IOMG96) */
+					0x108 0x1	/* GPIO (IOMG64) */
+				>;
+			};
+			uart3_pmx_func: uart3_pmx_func {
+				pinctrl-single,pins = <
+					0x160 0x2	/* UART3_CTS & UART3_RTS (IOMG85) */
+					0x164 0x2	/* UART3_RXD & UART3_TXD (IOMG86) */
+				>;
+			};
+			uart3_pmx_idle: uart3_pmx_idle {
+				pinctrl-single,pins = <
+					0x160 0x1	/* GPIO (IOMG85) */
+					0x164 0x1	/* GPIO (IOMG86) */
+				>;
+			};
+			uart4_pmx_func: uart4_pmx_func {
+				pinctrl-single,pins = <
+					0x168 0x0	/* UART4_CTS & UART4_RTS (IOMG87) */
+					0x16c 0x0	/* UART4_RXD (IOMG88) */
+					0x170 0x0	/* UART4_TXD (IOMG93) */
+				>;
+			};
+			uart4_pmx_idle: uart4_pmx_idle {
+				pinctrl-single,pins = <
+					0x168 0x1	/* GPIO (IOMG87) */
+					0x16c 0x1	/* GPIO (IOMG88) */
+					0x170 0x1	/* GPIO (IOMG93) */
+				>;
+			};
+			i2c0_pmx_func: i2c0_pmx_func {
+				pinctrl-single,pins = <
+					0x0b4 0x0	/* I2C0_SCL & I2C0_SDA (IOMG45) */
+				>;
+			};
+			i2c0_pmx_idle: i2c0_pmx_idle {
+				pinctrl-single,pins = <
+					0x0b4 0x1	/* GPIO (IOMG45) */
+				>;
+			};
+			i2c1_pmx_func: i2c1_pmx_func {
+				pinctrl-single,pins = <
+					0x0b8 0x0	/* I2C1_SCL & I2C1_SDA (IOMG46) */
+				>;
+			};
+			i2c1_pmx_idle: i2c1_pmx_idle {
+				pinctrl-single,pins = <
+					0x0b8 0x1	/* GPIO (IOMG46) */
+				>;
+			};
+			i2c2_pmx_func: i2c2_pmx_func {
+				pinctrl-single,pins = <
+					0x068 0x0	/* I2C2_SCL (IOMG26) */
+					0x06c 0x0	/* I2C2_SDA (IOMG27) */
+				>;
+			};
+			i2c2_pmx_idle: i2c2_pmx_idle {
+				pinctrl-single,pins = <
+					0x068 0x1	/* GPIO (IOMG26) */
+					0x06c 0x1	/* GPIO (IOMG27) */
+				>;
+			};
+			i2c3_pmx_func: i2c3_pmx_func {
+				pinctrl-single,pins = <
+					0x050 0x2	/* I2C3_SCL (IOMG20) */
+					0x054 0x2	/* I2C3_SDA (IOMG21) */
+				>;
+			};
+			i2c3_pmx_idle: i2c3_pmx_idle {
+				pinctrl-single,pins = <
+					0x050 0x1	/* GPIO (IOMG20) */
+					0x054 0x1	/* GPIO (IOMG21) */
+				>;
+			};
+			spi0_pmx_func: spi0_pmx_func {
+				pinctrl-single,pins = <
+					0x0d4 0x0	/* SPI0_CLK/SPI0_DI/SPI0_DO (IOMG53) */
+					0x0d8 0x0	/* SPI0_CS0 (IOMG54) */
+					0x0dc 0x0	/* SPI0_CS1 (IOMG55) */
+					0x0e0 0x0	/* SPI0_CS2 (IOMG56) */
+					0x0e4 0x0	/* SPI0_CS3 (IOMG57) */
+				>;
+			};
+			spi0_pmx_idle: spi0_pmx_idle {
+				pinctrl-single,pins = <
+					0x0d4 0x1	/* GPIO (IOMG53) */
+					0x0d8 0x1	/* GPIO (IOMG54) */
+					0x0dc 0x1	/* GPIO (IOMG55) */
+					0x0e0 0x1	/* GPIO (IOMG56) */
+					0x0e4 0x1	/* GPIO (IOMG57) */
+				>;
+			};
+			spi1_pmx_func: spi1_pmx_func {
+				pinctrl-single,pins = <
+					0x184 0x0	/* SPI1_CLK/SPI1_DI (IOMG98) */
+					0x0e8 0x0	/* SPI1_DO (IOMG58) */
+					0x0ec 0x0	/* SPI1_CS (IOMG95) */
+				>;
+			};
+			spi1_pmx_idle: spi1_pmx_idle {
+				pinctrl-single,pins = <
+					0x184 0x1	/* GPIO (IOMG98) */
+					0x0e8 0x1	/* GPIO (IOMG58) */
+					0x0ec 0x1	/* GPIO (IOMG95) */
+				>;
+			};
+			kpc_pmx_func: kpc_pmx_func {
+				pinctrl-single,pins = <
+					0x12c 0x0	/* KEY_IN0 (IOMG73) */
+					0x130 0x0	/* KEY_IN1 (IOMG74) */
+					0x134 0x0	/* KEY_IN2 (IOMG75) */
+					0x10c 0x0	/* KEY_OUT0 (IOMG65) */
+					0x110 0x0	/* KEY_OUT1 (IOMG66) */
+					0x114 0x0	/* KEY_OUT2 (IOMG67) */
+				>;
+			};
+			kpc_pmx_idle: kpc_pmx_idle {
+				pinctrl-single,pins = <
+					0x12c 0x1	/* GPIO (IOMG73) */
+					0x130 0x1	/* GPIO (IOMG74) */
+					0x134 0x1	/* GPIO (IOMG75) */
+					0x10c 0x1	/* GPIO (IOMG65) */
+					0x110 0x1	/* GPIO (IOMG66) */
+					0x114 0x1	/* GPIO (IOMG67) */
+				>;
+			};
+			gpio_key_func: gpio_key_func {
+				pinctrl-single,pins = <
+					0x10c 0x1	/* KEY_OUT0/GPIO (IOMG65) */
+					0x130 0x1	/* KEY_IN1/GPIO (IOMG74) */
+				>;
+			};
+			emmc_pmx_func: emmc_pmx_func {
+				pinctrl-single,pins = <
+					0x030 0x2	/* eMMC_CMD/eMMC_CLK (IOMG12) */
+					0x018 0x0	/* NAND_CS3_N (IOMG6) */
+					0x024 0x0	/* NAND_BUSY2_N (IOMG8) */
+					0x028 0x0	/* NAND_BUSY3_N (IOMG9) */
+					0x02c 0x2	/* eMMC_DATA[0:7] (IOMG10) */
+				>;
+			};
+			emmc_pmx_idle: emmc_pmx_idle {
+				pinctrl-single,pins = <
+					0x030 0x0	/* GPIO (IOMG12) */
+					0x018 0x1	/* GPIO (IOMG6) */
+					0x024 0x1	/* GPIO (IOMG8) */
+					0x028 0x1	/* GPIO (IOMG9) */
+					0x02c 0x1	/* GPIO (IOMG10) */
+				>;
+			};
+			sd_pmx_func: sd_pmx_func {
+				pinctrl-single,pins = <
+					0x0bc 0x0	/* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */
+					0x0c0 0x0	/* SD_DATA3 (IOMG48) */
+				>;
+			};
+			sd_pmx_idle: sd_pmx_idle {
+				pinctrl-single,pins = <
+					0x0bc 0x1	/* GPIO (IOMG47) */
+					0x0c0 0x1	/* GPIO (IOMG48) */
+				>;
+			};
+			nand_pmx_func: nand_pmx_func {
+				pinctrl-single,pins = <
+					0x00c 0x0	/* NAND_ALE/NAND_CLE/.../NAND_DATA[0:7] (IOMG3) */
+					0x010 0x0	/* NAND_CS1_N (IOMG4) */
+					0x014 0x0	/* NAND_CS2_N (IOMG5) */
+					0x018 0x0	/* NAND_CS3_N (IOMG6) */
+					0x01c 0x0	/* NAND_BUSY0_N (IOMG94) */
+					0x020 0x0	/* NAND_BUSY1_N (IOMG7) */
+					0x024 0x0	/* NAND_BUSY2_N (IOMG8) */
+					0x028 0x0	/* NAND_BUSY3_N (IOMG9) */
+					0x02c 0x0	/* NAND_DATA[8:15] (IOMG10) */
+				>;
+			};
+			nand_pmx_idle: nand_pmx_idle {
+				pinctrl-single,pins = <
+					0x00c 0x1	/* GPIO (IOMG3) */
+					0x010 0x1	/* GPIO (IOMG4) */
+					0x014 0x1	/* GPIO (IOMG5) */
+					0x018 0x1	/* GPIO (IOMG6) */
+					0x01c 0x1	/* GPIO (IOMG94) */
+					0x020 0x1	/* GPIO (IOMG7) */
+					0x024 0x1	/* GPIO (IOMG8) */
+					0x028 0x1	/* GPIO (IOMG9) */
+					0x02c 0x1	/* GPIO (IOMG10) */
+				>;
+			};
+			sdio_pmx_func: sdio_pmx_func {
+				pinctrl-single,pins = <
+					0x0c4 0x0	/* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */
+				>;
+			};
+			sdio_pmx_idle: sdio_pmx_idle {
+				pinctrl-single,pins = <
+					0x0c4 0x1	/* GPIO (IOMG49) */
+				>;
+			};
+			audio_out_pmx_func: audio_out_pmx_func {
+				pinctrl-single,pins = <
+					0x0f0 0x1	/* GPIO (IOMG59), audio spk & earphone */
+				>;
+			};
+		};
+
+		pmx1: pinmux at fc803800 {
+			pinctrl-names = "default";
+			pinctrl-0 = <	&board_pu_pins &board_pd_pins &board_pd_ps_pins
+					&board_np_pins &board_ps_pins &kpc_cfg_func
+					&audio_out_cfg_func>;
+			board_pu_pins: board_pu_pins {
+				pinctrl-single,pins = <
+					0x014 0		/* GPIO_158 (IOCFG2) */
+					0x018 0		/* GPIO_159 (IOCFG3) */
+					0x01c 0		/* BOOT_MODE0 (IOCFG4) */
+					0x020 0		/* BOOT_MODE1 (IOCFG5) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <1 1 0 1>;
+			};
+			board_pd_pins: board_pd_pins {
+				pinctrl-single,pins = <
+					0x038 0		/* eFUSE_DOUT (IOCFG11) */
+					0x150 0		/* ISP_GPIO8 (IOCFG93) */
+					0x154 0		/* ISP_GPIO9 (IOCFG94) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			board_pd_ps_pins: board_pd_ps_pins {
+				pinctrl-single,pins = <
+					0x2d8 0		/* CLK_OUT0 (IOCFG190) */
+					0x004 0		/* PMU_SPI_DATA (IOCFG192) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			board_np_pins: board_np_pins {
+				pinctrl-single,pins = <
+					0x24c 0		/* KEYPAD_OUT7 (IOCFG155) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			board_ps_pins: board_ps_pins {
+				pinctrl-single,pins = <
+					0x000 0		/* PMU_SPI_CLK (IOCFG191) */
+					0x008 0		/* PMU_SPI_CS_N (IOCFG193) */
+				>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			uart0_cfg_func: uart0_cfg_func {
+				pinctrl-single,pins = <
+					0x208 0		/* UART0_RXD (IOCFG138) */
+					0x20c 0		/* UART0_TXD (IOCFG139) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart0_cfg_idle: uart0_cfg_idle {
+				pinctrl-single,pins = <
+					0x208 0		/* UART0_RXD (IOCFG138) */
+					0x20c 0		/* UART0_TXD (IOCFG139) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart1_cfg_func: uart1_cfg_func {
+				pinctrl-single,pins = <
+					0x210 0		/* UART1_CTS (IOCFG140) */
+					0x214 0		/* UART1_RTS (IOCFG141) */
+					0x218 0		/* UART1_RXD (IOCFG142) */
+					0x21c 0		/* UART1_TXD (IOCFG143) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart1_cfg_idle: uart1_cfg_idle {
+				pinctrl-single,pins = <
+					0x210 0		/* UART1_CTS (IOCFG140) */
+					0x214 0		/* UART1_RTS (IOCFG141) */
+					0x218 0		/* UART1_RXD (IOCFG142) */
+					0x21c 0		/* UART1_TXD (IOCFG143) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart2_cfg_func: uart2_cfg_func {
+				pinctrl-single,pins = <
+					0x220 0		/* UART2_CTS (IOCFG144) */
+					0x224 0		/* UART2_RTS (IOCFG145) */
+					0x228 0		/* UART2_RXD (IOCFG146) */
+					0x22c 0		/* UART2_TXD (IOCFG147) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart2_cfg_idle: uart2_cfg_idle {
+				pinctrl-single,pins = <
+					0x220 0		/* GPIO (IOCFG144) */
+					0x224 0		/* GPIO (IOCFG145) */
+					0x228 0		/* GPIO (IOCFG146) */
+					0x22c 0		/* GPIO (IOCFG147) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart3_cfg_func: uart3_cfg_func {
+				pinctrl-single,pins = <
+					0x294 0		/* UART3_CTS (IOCFG173) */
+					0x298 0		/* UART3_RTS (IOCFG174) */
+					0x29c 0		/* UART3_RXD (IOCFG175) */
+					0x2a0 0		/* UART3_TXD (IOCFG176) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart3_cfg_idle: uart3_cfg_idle {
+				pinctrl-single,pins = <
+					0x294 0		/* UART3_CTS (IOCFG173) */
+					0x298 0		/* UART3_RTS (IOCFG174) */
+					0x29c 0		/* UART3_RXD (IOCFG175) */
+					0x2a0 0		/* UART3_TXD (IOCFG176) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			uart4_cfg_func: uart4_cfg_func {
+				pinctrl-single,pins = <
+					0x2a4 0		/* UART4_CTS (IOCFG177) */
+					0x2a8 0		/* UART4_RTS (IOCFG178) */
+					0x2ac 0		/* UART4_RXD (IOCFG179) */
+					0x2b0 0		/* UART4_TXD (IOCFG180) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			i2c0_cfg_func: i2c0_cfg_func {
+				pinctrl-single,pins = <
+					0x17c 0		/* I2C0_SCL (IOCFG103) */
+					0x180 0		/* I2C0_SDA (IOCFG104) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			i2c1_cfg_func: i2c1_cfg_func {
+				pinctrl-single,pins = <
+					0x184 0		/* I2C1_SCL (IOCFG105) */
+					0x188 0		/* I2C1_SDA (IOCFG106) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			i2c2_cfg_func: i2c2_cfg_func {
+				pinctrl-single,pins = <
+					0x118 0		/* I2C2_SCL (IOCFG79) */
+					0x11c 0		/* I2C2_SDA (IOCFG80) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			i2c3_cfg_func: i2c3_cfg_func {
+				pinctrl-single,pins = <
+					0x100 0		/* I2C3_SCL (IOCFG73) */
+					0x104 0		/* I2C3_SDA (IOCFG74) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			spi0_cfg_func1: spi0_cfg_func1 {
+				pinctrl-single,pins = <
+					0x1d4 0		/* SPI0_CLK (IOCFG125) */
+					0x1d8 0		/* SPI0_DI (IOCFG126) */
+					0x1dc 0		/* SPI0_DO (IOCFG127) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			spi0_cfg_func2: spi0_cfg_func2 {
+				pinctrl-single,pins = <
+					0x1e0 0		/* SPI0_CS0 (IOCFG128) */
+					0x1e4 0		/* SPI0_CS1 (IOCFG129) */
+					0x1e8 0		/* SPI0_CS2 (IOCFG130 */
+					0x1ec 0		/* SPI0_CS3 (IOCFG131) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <1 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			spi1_cfg_func1: spi1_cfg_func1 {
+				pinctrl-single,pins = <
+					0x1f0 0		/* SPI1_CLK (IOCFG132) */
+					0x1f4 0		/* SPI1_DI (IOCFG133) */
+					0x1f8 0		/* SPI1_DO (IOCFG134) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			spi1_cfg_func2: spi1_cfg_func2 {
+				pinctrl-single,pins = <
+					0x1fc 0		/* SPI1_CS (IOCFG135) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <1 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			kpc_cfg_func: kpc_cfg_func {
+				pinctrl-single,pins = <
+					0x250 0		/* KEY_IN0 (IOCFG156) */
+					0x254 0		/* KEY_IN1 (IOCFG157) */
+					0x258 0		/* KEY_IN2 (IOCFG158) */
+					0x230 0		/* KEY_OUT0 (IOCFG148) */
+					0x234 0		/* KEY_OUT1 (IOCFG149) */
+					0x238 0		/* KEY_OUT2 (IOCFG150) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+			emmc_cfg_func: emmc_cfg_func {
+				pinctrl-single,pins = <
+					0x0ac 0		/* eMMC_CMD (IOCFG40) */
+					0x0b0 0		/* eMMC_CLK (IOCFG41) */
+					0x058 0		/* NAND_CS3_N (IOCFG19) */
+					0x064 0		/* NAND_BUSY2_N (IOCFG22) */
+					0x068 0		/* NAND_BUSY3_N (IOCFG23) */
+					0x08c 0		/* NAND_DATA8 (IOCFG32) */
+					0x090 0		/* NAND_DATA9 (IOCFG33) */
+					0x094 0		/* NAND_DATA10 (IOCFG34) */
+					0x098 0		/* NAND_DATA11 (IOCFG35) */
+					0x09c 0		/* NAND_DATA12 (IOCFG36) */
+					0x0a0 0		/* NAND_DATA13 (IOCFG37) */
+					0x0a4 0		/* NAND_DATA14 (IOCFG38) */
+					0x0a8 0		/* NAND_DATA15 (IOCFG39) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <1 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			sd_cfg_func1: sd_cfg_func1 {
+				pinctrl-single,pins = <
+					0x18c 0		/* SD_CLK (IOCFG107) */
+					0x190 0		/* SD_CMD (IOCFG108) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			sd_cfg_func2: sd_cfg_func2 {
+				pinctrl-single,pins = <
+					0x194 0		/* SD_DATA0 (IOCFG109) */
+					0x198 0		/* SD_DATA1 (IOCFG110) */
+					0x19c 0		/* SD_DATA2 (IOCFG111) */
+					0x1a0 0		/* SD_DATA3 (IOCFG112) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x70 0xf0>;
+			};
+			nand_cfg_func1: nand_cfg_func1 {
+				pinctrl-single,pins = <
+					0x03c 0		/* NAND_ALE (IOCFG12) */
+					0x040 0		/* NAND_CLE (IOCFG13) */
+					0x06c 0		/* NAND_DATA0 (IOCFG24) */
+					0x070 0		/* NAND_DATA1 (IOCFG25) */
+					0x074 0		/* NAND_DATA2 (IOCFG26) */
+					0x078 0		/* NAND_DATA3 (IOCFG27) */
+					0x07c 0		/* NAND_DATA4 (IOCFG28) */
+					0x080 0		/* NAND_DATA5 (IOCFG29) */
+					0x084 0		/* NAND_DATA6 (IOCFG30) */
+					0x088 0		/* NAND_DATA7 (IOCFG31) */
+					0x08c 0		/* NAND_DATA8 (IOCFG32) */
+					0x090 0		/* NAND_DATA9 (IOCFG33) */
+					0x094 0		/* NAND_DATA10 (IOCFG34) */
+					0x098 0		/* NAND_DATA11 (IOCFG35) */
+					0x09c 0		/* NAND_DATA12 (IOCFG36) */
+					0x0a0 0		/* NAND_DATA13 (IOCFG37) */
+					0x0a4 0		/* NAND_DATA14 (IOCFG38) */
+					0x0a8 0		/* NAND_DATA15 (IOCFG39) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			nand_cfg_func2: nand_cfg_func2 {
+				pinctrl-single,pins = <
+					0x044 0		/* NAND_RE_N (IOCFG14) */
+					0x048 0		/* NAND_WE_N (IOCFG15) */
+					0x04c 0		/* NAND_CS0_N (IOCFG16) */
+					0x050 0		/* NAND_CS1_N (IOCFG17) */
+					0x054 0		/* NAND_CS2_N (IOCFG18) */
+					0x058 0		/* NAND_CS3_N (IOCFG19) */
+					0x05c 0		/* NAND_BUSY0_N (IOCFG20) */
+					0x060 0		/* NAND_BUSY1_N (IOCFG21) */
+					0x064 0		/* NAND_BUSY2_N (IOCFG22) */
+					0x068 0		/* NAND_BUSY3_N (IOCFG23) */
+				>;
+				pinctrl-single,bias-pulldown = <0 2 0 2>;
+				pinctrl-single,bias-pullup = <1 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			sdio_cfg_func: sdio_cfg_func {
+				pinctrl-single,pins = <
+					0x1a4 0		/* SDIO0_CLK (IOCG113) */
+					0x1a8 0		/* SDIO0_CMD (IOCG114) */
+					0x1ac 0		/* SDIO0_DATA0 (IOCG115) */
+					0x1b0 0		/* SDIO0_DATA1 (IOCG116) */
+					0x1b4 0		/* SDIO0_DATA2 (IOCG117) */
+					0x1b8 0		/* SDIO0_DATA3 (IOCG118) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+				pinctrl-single,drive-strength = <0x30 0xf0>;
+			};
+			audio_out_cfg_func: audio_out_cfg_func {
+				pinctrl-single,pins = <
+					0x200 0		/* GPIO (IOCFG136) */
+					0x204 0		/* GPIO (IOCFG137) */
+				>;
+				pinctrl-single,bias-pulldown = <2 2 0 2>;
+				pinctrl-single,bias-pullup = <0 1 0 1>;
+			};
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		call {
+			label = "call";
+			gpios = <&gpio17 2 0>;
+			linux,code = <169>;	/* KEY_PHONE */
+		};
+	};
+};
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2e67a27..59f9753 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -6,6 +6,7 @@ CONFIG_MACH_ARMADA_370=y
 CONFIG_ARCH_SIRF=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_HI3xxx=y
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_WM8850=y
-- 
1.8.1.2

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

* [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 with device tree
  2013-06-17  8:56 ` [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 " Haojian Zhuang
@ 2013-06-17 17:41   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-06-17 21:39     ` Olof Johansson
  2013-06-17 22:05   ` Olof Johansson
  1 sibling, 1 reply; 15+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-17 17:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 16:56 Mon 17 Jun     , Haojian Zhuang wrote:
> Enable Hisilicon Hi4511 development platform with device tree support.
> 

please use macro for DT I'll review this end of the week

Best Regards,
J.
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  arch/arm/boot/dts/Makefile          |    1 +
>  arch/arm/boot/dts/hi3620.dtsi       | 1147 +++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/hi4511.dts        |  648 ++++++++++++++++++++
>  arch/arm/configs/multi_v7_defconfig |    1 +
>  4 files changed, 1797 insertions(+)
>  create mode 100644 arch/arm/boot/dts/hi3620.dtsi
>  create mode 100644 arch/arm/boot/dts/hi4511.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index f0895c5..216f983 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -58,6 +58,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
>  	exynos5250-smdk5250.dtb \
>  	exynos5250-snow.dtb \
>  	exynos5440-ssdk5440.dtb
> +dtb-$(CONFIG_ARCH_HI3xxx) += hi4511.dtb
>  dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
>  	ecx-2000.dtb
>  dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
> diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
> new file mode 100644
> index 0000000..1f0a4aa
> --- /dev/null
> +++ b/arch/arm/boot/dts/hi3620.dtsi
> @@ -0,0 +1,1147 @@
> +/*
> + * Hisilicon Ltd. Hi3620 SoC
> + *
> + * Copyright (C) 2012-2013 Hisilicon Ltd.
> + * Copyright (C) 2012-2013 Linaro Ltd.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * publishhed by the Free Software Foundation.
> + */
> +
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +		serial3 = &uart3;
> +		serial4 = &uart4;
> +	};
> +
> +	osc32k: osc at 0 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		clock-output-names = "osc32khz";
> +	};
> +	osc26m: osc at 1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +		clock-output-names = "osc26mhz";
> +	};
> +	pclk: clk at 0 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +		clock-output-names = "apb_pclk";
> +	};
> +	pll_arm0: clk at 1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1600000000>;
> +		clock-output-names = "armpll0";
> +	};
> +	pll_arm1: clk at 2 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1600000000>;
> +		clock-output-names = "armpll1";
> +	};
> +	pll_peri: clk at 3 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1440000000>;
> +		clock-output-names = "armpll2";
> +	};
> +	pll_usb: clk at 4 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1440000000>;
> +		clock-output-names = "armpll3";
> +	};
> +	pll_hdmi: clk at 5 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1188000000>;
> +		clock-output-names = "armpll4";
> +	};
> +	pll_gpu: clk at 6 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1300000000>;
> +		clock-output-names = "armpll5";
> +	};
> +
> +	amba {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "arm,amba-bus";
> +		interrupt-parent = <&intc>;
> +		ranges;
> +
> +		pmctrl: pmctrl at fca08000 {
> +			compatible = "hisilicon,pmctrl";
> +			reg = <0xfca08000 0x1000>;
> +		};
> +
> +		sctrl: sctrl at fc802000 {
> +			compatible = "hisilicon,sctrl";
> +			reg = <0xfc802000 0x1000>;
> +
> +			uart0_mux: uart0_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &pclk>;
> +				clock-output-names = "uart0_mux";
> +				/* reg_offset, mask bits */
> +				hisilicon,clkmux-reg = <0x100 0x80>;
> +				/* each item value */
> +				hisilicon,clkmux-table = <0 0x80>;
> +			};
> +			uart1_mux: uart1_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &pclk>;
> +				clock-output-names = "uart1_mux";
> +				hisilicon,clkmux-reg = <0x100 0x100>;
> +				hisilicon,clkmux-table = <0x0 0x100>;
> +			};
> +			uart2_mux: uart2_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &pclk>;
> +				clock-output-names = "uart2_mux";
> +				hisilicon,clkmux-reg = <0x100 0x200>;
> +				hisilicon,clkmux-table = <0 0x200>;
> +			};
> +			uart3_mux: uart3_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &pclk>;
> +				clock-output-names = "uart3_mux";
> +				hisilicon,clkmux-reg = <0x100 0x400>;
> +				hisilicon,clkmux-table = <0 0x400>;
> +			};
> +			uart4_mux: uart4_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &pclk>;
> +				clock-output-names = "uart4_mux";
> +				hisilicon,clkmux-reg = <0x100 0x800>;
> +				hisilicon,clkmux-table = <0 0x800>;
> +			};
> +			rclk_cfgaxi: rclk_cfgaxi {
> +				compatible = "fixed-factor-clock";
> +				#clock-cells = <0>;
> +				clocks = <&pll_peri>;
> +				clock-output-names = "rclk_cfgaxi";
> +				clock-mult = <1>;
> +				clock-div = <30>;
> +			};
> +			spi0_mux: spi0_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &rclk_cfgaxi>;
> +				clock-output-names = "spi0_mux";
> +				hisilicon,clkmux-reg = <0x100 0x1000>;
> +				hisilicon,clkmux-table = <0 0x1000>;
> +			};
> +			spi1_mux: spi1_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &rclk_cfgaxi>;
> +				clock-output-names = "spi1_mux";
> +				hisilicon,clkmux-reg = <0x100 0x2000>;
> +				hisilicon,clkmux-table = <0 0x2000>;
> +			};
> +			spi2_mux: spi2_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m &rclk_cfgaxi>;
> +				clock-output-names = "spi2_mux";
> +				hisilicon,clkmux-reg = <0x100 0x4000>;
> +				hisilicon,clkmux-table = <0 0x4000>;
> +			};
> +			pwm0_mux: pwm0_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &osc26m>;
> +				clock-output-names = "pwm0_mux";
> +				hisilicon,clkmux-reg = <0x104 0x400>;
> +				hisilicon,clkmux-table = <0 0x400>;
> +			};
> +			pwm1_mux: pwm1_mux {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &osc26m>;
> +				clock-output-names = "pwm1_mux";
> +				hisilicon,clkmux-reg = <0x104 0x800>;
> +				hisilicon,clkmux-table = <0 0x800>;
> +			};
> +			timer0_mux: timer0_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk01>;
> +				clock-output-names = "timer0_mux";
> +				hisilicon,clkmux-reg = <0 0x8000>;
> +				hisilicon,clkmux-table = <0 0x8000>;
> +			};
> +			timer1_mux: timer1_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk01>;
> +				clock-output-names = "timer1_mux";
> +				hisilicon,clkmux-reg = <0 0x20000>;
> +				hisilicon,clkmux-table = <0 0x20000>;
> +			};
> +			timer2_mux: timer2_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk23>;
> +				clock-output-names = "timer2_mux";
> +				hisilicon,clkmux-reg = <0 0x80000>;
> +				hisilicon,clkmux-table = <0 0x80000>;
> +			};
> +			timer3_mux: timer3_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk23>;
> +				clock-output-names = "timer3_mux";
> +				hisilicon,clkmux-reg = <0 0x200000>;
> +				hisilicon,clkmux-table = <0 0x200000>;
> +			};
> +			timer4_mux: timer4_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk45>;
> +				clock-output-names = "timer4_mux";
> +				hisilicon,clkmux-reg = <0x18 0x1>;
> +				hisilicon,clkmux-table = <0 0x1>;
> +			};
> +			timer5_mux: timer5_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk45>;
> +				clock-output-names = "timer5_mux";
> +				hisilicon,clkmux-reg = <0x18 0x4>;
> +				hisilicon,clkmux-table = <0 0x4>;
> +			};
> +			timer6_mux: timer6_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk67>;
> +				clock-output-names = "timer6_mux";
> +				hisilicon,clkmux-reg = <0x18 0x10>;
> +				hisilicon,clkmux-table = <0 0x10>;
> +			};
> +			timer7_mux: timer7_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk67>;
> +				clock-output-names = "timer7_mux";
> +				hisilicon,clkmux-reg = <0x18 0x40>;
> +				hisilicon,clkmux-table = <0 0x40>;
> +			};
> +			timer8_mux: timer8_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk89>;
> +				clock-output-names = "timer8_mux";
> +				hisilicon,clkmux-reg = <0x18 0x100>;
> +				hisilicon,clkmux-table = <0 0x100>;
> +			};
> +			timer9_mux: timer9_mux {
> +				compatible = "hisilicon,clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&osc32k &timerclk89>;
> +				clock-output-names = "timer9_mux";
> +				hisilicon,clkmux-reg = <0x18 0x400>;
> +				hisilicon,clkmux-table = <0 0x400>;
> +			};
> +			rclk_shareAXI: rclk_shareAXI {
> +				compatible = "hisilicon,hi3620-clk-mux";
> +				#clock-cells = <0>;
> +				clocks = <&pll_usb &pll_peri>;
> +				clock-output-names = "rclk_shareAXI";
> +				hisilicon,clkmux-reg = <0x100 0x8000>;
> +				hisilicon,clkmux-table = <0 0x8000>;
> +			};
> +			uartclk0: uartclk0 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&uart0_mux>;
> +				clock-output-names = "uartclk0";
> +				hisilicon,hi3620-clkreset = <0x98 0x10000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x10000>;
> +			};
> +			uartclk1: uartclk1 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&uart1_mux>;
> +				clock-output-names = "uartclk1";
> +				hisilicon,hi3620-clkreset = <0x98 0x20000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x20000>;
> +			};
> +			uartclk2: uartclk2 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&uart2_mux>;
> +				clock-output-names = "uartclk2";
> +				hisilicon,hi3620-clkreset = <0x98 0x40000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x40000>;
> +			};
> +			uartclk3: uartclk3 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&uart3_mux>;
> +				clock-output-names = "uartclk3";
> +				hisilicon,hi3620-clkreset = <0x98 0x80000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x80000>;
> +			};
> +			uartclk4: uartclk4 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&uart4_mux>;
> +				clock-output-names = "uartclk4";
> +				hisilicon,hi3620-clkreset = <0x98 0x100000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x100000>;
> +			};
> +			gpioclk0: gpioclk0 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk0";
> +				hisilicon,hi3620-clkreset = <0x80 0x100>;
> +				hisilicon,hi3620-clkgate = <0x20 0x100>;
> +			};
> +			gpioclk1: gpioclk1 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk1";
> +				hisilicon,hi3620-clkreset = <0x80 0x200>;
> +				hisilicon,hi3620-clkgate = <0x20 0x200>;
> +			};
> +			gpioclk2: gpioclk2 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk2";
> +				hisilicon,hi3620-clkreset = <0x80 0x400>;
> +				hisilicon,hi3620-clkgate = <0x20 0x400>;
> +			};
> +			gpioclk3: gpioclk3 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk3";
> +				hisilicon,hi3620-clkreset = <0x80 0x800>;
> +				hisilicon,hi3620-clkgate = <0x20 0x800>;
> +			};
> +			gpioclk4: gpioclk4 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk4";
> +				hisilicon,hi3620-clkreset = <0x80 0x1000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x1000>;
> +			};
> +			gpioclk5: gpioclk5 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk5";
> +				hisilicon,hi3620-clkreset = <0x80 0x2000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x2000>;
> +			};
> +			gpioclk6: gpioclk6 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk6";
> +				hisilicon,hi3620-clkreset = <0x80 0x4000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x4000>;
> +			};
> +			gpioclk7: gpioclk7 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk7";
> +				hisilicon,hi3620-clkreset = <0x80 0x8000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x8000>;
> +			};
> +			gpioclk8: gpioclk8 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk8";
> +				hisilicon,hi3620-clkreset = <0x80 0x10000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x10000>;
> +			};
> +			gpioclk9: gpioclk9 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk9";
> +				hisilicon,hi3620-clkreset = <0x80 0x20000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x20000>;
> +			};
> +			gpioclk10: gpioclk10 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk10";
> +				hisilicon,hi3620-clkreset = <0x80 0x40000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x40000>;
> +			};
> +			gpioclk11: gpioclk11 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk11";
> +				hisilicon,hi3620-clkreset = <0x80 0x80000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x80000>;
> +			};
> +			gpioclk12: gpioclk12 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk12";
> +				hisilicon,hi3620-clkreset = <0x80 0x100000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x100000>;
> +			};
> +			gpioclk13: gpioclk13 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk13";
> +				hisilicon,hi3620-clkreset = <0x80 0x200000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x200000>;
> +			};
> +			gpioclk14: gpioclk14 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk14";
> +				hisilicon,hi3620-clkreset = <0x80 0x400000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x400000>;
> +			};
> +			gpioclk15: gpioclk15 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk15";
> +				hisilicon,hi3620-clkreset = <0x80 0x800000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x800000>;
> +			};
> +			gpioclk16: gpioclk16 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk16";
> +				hisilicon,hi3620-clkreset = <0x80 0x1000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x1000000>;
> +			};
> +			gpioclk17: gpioclk17 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk17";
> +				hisilicon,hi3620-clkreset = <0x80 0x2000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x2000000>;
> +			};
> +			gpioclk18: gpioclk18 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk18";
> +				hisilicon,hi3620-clkreset = <0x80 0x4000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x4000000>;
> +			};
> +			gpioclk19: gpioclk19 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk19";
> +				hisilicon,hi3620-clkreset = <0x80 0x8000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x8000000>;
> +			};
> +			gpioclk20: gpioclk20 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk20";
> +				hisilicon,hi3620-clkreset = <0x80 0x10000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x10000000>;
> +			};
> +			gpioclk21: gpioclk21 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pclk>;
> +				clock-output-names = "gpioclk21";
> +				hisilicon,hi3620-clkreset = <0x80 0x20000000>;
> +				hisilicon,hi3620-clkgate = <0x20 0x20000000>;
> +			};
> +			spiclk0: spiclk0 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&spi0_mux>;
> +				clock-output-names = "spiclk0";
> +				hisilicon,hi3620-clkreset = <0x98 0x200000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x200000>;
> +			};
> +			spiclk1: spiclk1 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&spi1_mux>;
> +				clock-output-names = "spiclk1";
> +				hisilicon,hi3620-clkreset = <0x98 0x400000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x400000>;
> +			};
> +			spiclk2: spiclk2 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&spi2_mux>;
> +				clock-output-names = "spiclk2";
> +				hisilicon,hi3620-clkreset = <0x98 0x800000>;
> +				hisilicon,hi3620-clkgate = <0x40 0x800000>;
> +			};
> +			pwmclk0: pwmclk0 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pwm0_mux>;
> +				clock-output-names = "pwmclk0";
> +				hisilicon,hi3620-clkreset = <0x98 0x80>;
> +				hisilicon,hi3620-clkgate = <0x40 0x80>;
> +			};
> +			pwmclk1: pwmclk1 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&pwm1_mux>;
> +				clock-output-names = "pwmclk1";
> +				hisilicon,hi3620-clkreset = <0x98 0x100>;
> +				hisilicon,hi3620-clkgate = <0x40 0x100>;
> +			};
> +			timerclk01: timerclk01 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m>;
> +				clock-output-names = "timerclk01";
> +				hisilicon,hi3620-clkreset = <0x80 0x1>;
> +				hisilicon,hi3620-clkgate = <0x20 0x3>;
> +			};
> +			timerclk23: timerclk23 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m>;
> +				clock-output-names = "timerclk23";
> +				hisilicon,hi3620-clkreset = <0x80 0x2>;
> +				hisilicon,hi3620-clkgate = <0x20 0xc>;
> +			};
> +			timerclk45: timerclk45 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m>;
> +				clock-output-names = "timerclk45";
> +				hisilicon,hi3620-clkreset = <0x98 0x8>;
> +				hisilicon,hi3620-clkgate = <0x40 0x8>;
> +			};
> +			timerclk67: timerclk67 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m>;
> +				clock-output-names = "timerclk67";
> +				hisilicon,hi3620-clkreset = <0x98 0x10>;
> +				hisilicon,hi3620-clkgate = <0x40 0x10>;
> +			};
> +			timerclk89: timerclk89 {
> +				compatible = "hisilicon,hi3620-clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&osc26m>;
> +				clock-output-names = "timerclk89";
> +				hisilicon,hi3620-clkreset = <0x98 0x20>;
> +				hisilicon,hi3620-clkgate = <0x40 0x20>;
> +			};
> +			timclk0: timclk0 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer0_mux>;
> +				clock-output-names = "timclk0";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0 16>;
> +			};
> +			timclk1: timclk1 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer1_mux>;
> +				clock-output-names = "timclk1";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0 18>;
> +			};
> +			timclk2: timclk2 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer2_mux>;
> +				clock-output-names = "timclk2";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0 20>;
> +			};
> +			timclk3: timclk3 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer3_mux>;
> +				clock-output-names = "timclk3";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0 22>;
> +			};
> +			timclk4: timclk4 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer4_mux>;
> +				clock-output-names = "timclk4";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 0>;
> +			};
> +			timclk5: timclk5 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer5_mux>;
> +				clock-output-names = "timclk5";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 2>;
> +			};
> +			timclk6: timclk6 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer6_mux>;
> +				clock-output-names = "timclk6";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 4>;
> +			};
> +			timclk7: timclk7 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer7_mux>;
> +				clock-output-names = "timclk7";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 6>;
> +			};
> +			timclk8: timclk8 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer8_mux>;
> +				clock-output-names = "timclk8";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 8>;
> +			};
> +			timclk9: timclk9 {
> +				compatible = "hisilicon,clk-gate";
> +				#clock-cells = <0>;
> +				clocks = <&timer9_mux>;
> +				clock-output-names = "timclk9";
> +				hisilicon,clkgate-inverted;
> +				hisilicon,clkgate = <0x18 10>;
> +			};
> +			dtable: dtable {
> +				#hisilicon,clkdiv-table-cells = <2>;
> +			};
> +			div_shareaxi: div_shareaxi {
> +				compatible = "hisilicon,hi3620-clk-div";
> +				#clock-cells = <0>;
> +				clocks = <&rclk_shareAXI>;
> +				clock-output-names = "shareAXI_div";
> +				hisilicon,clkdiv-table = <
> +					&dtable 0 1 &dtable 1 2 &dtable 2 3 &dtable 3 4
> +					&dtable 4 5 &dtable 5 6 &dtable 6 7 &dtable 7 8
> +					&dtable 8 9 &dtable 9 10 &dtable 10 11 &dtable 11 12
> +					&dtable 12 13 &dtable 13 14 &dtable 14 15 &dtable 15 16
> +					&dtable 16 17 &dtable 17 18 &dtable 18 19 &dtable 19 20
> +					&dtable 20 21 &dtable 21 22 &dtable 22 23 &dtable 23 24
> +					&dtable 24 25 &dtable 25 26 &dtable 26 27 &dtable 27 28
> +					&dtable 28 29 &dtable 29 30 &dtable 30 31 &dtable 31 32>;
> +				/* divider register offset, mask */
> +				hisilicon,clkdiv = <0x100 0x1f>;
> +			};
> +			div_cfgaxi: div_cfgaxi {
> +				compatible = "hisilicon,hi3620-clk-div";
> +				#clock-cells = <0>;
> +				clocks = <&div_shareaxi>;
> +				clock-output-names = "cfgAXI_div";
> +				hisilicon,clkdiv-table = <&dtable 0x01 2>;
> +				hisilicon,clkdiv = <0x100 0x60>;
> +			};
> +		};
> +
> +		l2: l2-cache {
> +			compatible = "arm,pl310-cache";
> +			reg = <0xfc10000 0x100000>;
> +			interrupts = <0 15 4>;
> +			cache-unified;
> +			cache-level = <2>;
> +		};
> +
> +		intc: interrupt-controller at fc001000 {
> +			compatible = "arm,cortex-a9-gic";
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +			/* gic dist base, gic cpu base */
> +			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
> +		};
> +
> +		timer0: timer at fc800000 {
> +			compatible = "arm,sp804", "arm,primecell";
> +			reg = <0xfc800000 0x1000>;
> +			/* timer00 & timer01 */
> +			interrupts = <0 0 4>, <0 1 4>;
> +			clocks = <&timclk0 &timclk1>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		timer1: timer at fc801000 {
> +			compatible = "arm,sp804", "arm,primecell";
> +			reg = <0xfc801000 0x1000>;
> +			/* timer10 & timer11 */
> +			interrupts = <0 2 4>, <0 3 4>;
> +			clocks = <&timclk2 &timclk3>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		timer2: timer at fca01000 {
> +			compatible = "arm,sp804", "arm,primecell";
> +			reg = <0xfca01000 0x1000>;
> +			/* timer20 & timer21 */
> +			interrupts = <0 4 4>, <0 5 4>;
> +			clocks = <&timclk4 &timclk5>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		timer3: timer at fca02000 {
> +			compatible = "arm,sp804", "arm,primecell";
> +			reg = <0xfca02000 0x1000>;
> +			/* timer30 & timer31 */
> +			interrupts = <0 6 4>, <0 7 4>;
> +			clocks = <&timclk6 &timclk7>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		timer4: timer at fca03000 {
> +			compatible = "arm,sp804", "arm,primecell";
> +			reg = <0xfca03000 0x1000>;
> +			/* timer40 & timer41 */
> +			interrupts = <0 96 4>, <0 97 4>;
> +			clocks = <&timclk8 &timclk9>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		uart0: uart at fcb00000 {
> +			compatible = "arm,pl011", "arm,primecell";
> +			reg = <0xfcb00000 0x1000>;
> +			interrupts = <0 20 4>;
> +			clocks = <&uartclk0>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		uart1: uart at fcb01000 {
> +			compatible = "arm,pl011", "arm,primecell";
> +			reg = <0xfcb01000 0x1000>;
> +			interrupts = <0 21 4>;
> +			clocks = <&uartclk1>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		uart2: uart at fcb02000 {
> +			compatible = "arm,pl011", "arm,primecell";
> +			reg = <0xfcb02000 0x1000>;
> +			interrupts = <0 22 4>;
> +			clocks = <&uartclk2>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		uart3: uart at fcb03000 {
> +			compatible = "arm,pl011", "arm,primecell";
> +			reg = <0xfcb03000 0x1000>;
> +			interrupts = <0 23 4>;
> +			clocks = <&uartclk3>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		uart4: uart at fcb04000 {
> +			compatible = "arm,pl011", "arm,primecell";
> +			reg = <0xfcb04000 0x1000>;
> +			interrupts = <0 24 4>;
> +			clocks = <&uartclk4>;
> +			clock-names = "apb_pclk";
> +			status = "disabled";
> +		};
> +
> +		gpio0: gpio at fc806000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc806000 0x1000>;
> +			interrupts = <0 64 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 2 0 1 &pmx0 3 0 1 &pmx0 4 0 1
> +					&pmx0 5 0 1 &pmx0 6 1 1 &pmx0 7 2 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk0>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio1: gpio at fc807000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc807000 0x1000>;
> +			interrupts = <0 65 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
> +					&pmx0 3 3 1 &pmx0 4 3 1 &pmx0 5 4 1
> +					&pmx0 6 5 1 &pmx0 7 6 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk1>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio2: gpio at fc808000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc808000 0x1000>;
> +			interrupts = <0 66 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 7 1 &pmx0 1 8 1 &pmx0 2 9 1
> +					&pmx0 3 10 1 &pmx0 4 3 1 &pmx0 5 3 1
> +					&pmx0 6 3 1 &pmx0 7 3 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk2>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio3: gpio at fc809000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc809000 0x1000>;
> +			interrupts = <0 67 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
> +					&pmx0 3 3 1 &pmx0 4 11 1 &pmx0 5 11 1
> +					&pmx0 6 11 1 &pmx0 7 11 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk3>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio4: gpio at fc80a000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80a000 0x1000>;
> +			interrupts = <0 68 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 11 1 &pmx0 1 11 1 &pmx0 2 11 1
> +					&pmx0 3 11 1 &pmx0 4 12 1 &pmx0 5 12 1
> +					&pmx0 6 13 1 &pmx0 7 13 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk4>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio5: gpio at fc80b000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80b000 0x1000>;
> +			interrupts = <0 69 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 14 1 &pmx0 1 15 1 &pmx0 2 16 1
> +					&pmx0 3 16 1 &pmx0 4 16 1 &pmx0 5 16 1
> +					&pmx0 6 16 1 &pmx0 7 16 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk5>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio6: gpio at fc80c000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80c000 0x1000>;
> +			interrupts = <0 70 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 16 1 &pmx0 1 16 1 &pmx0 2 17 1
> +					&pmx0 3 17 1 &pmx0 4 18 1 &pmx0 5 18 1
> +					&pmx0 6 18 1 &pmx0 7 19 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk6>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio7: gpio at fc80d000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80d000 0x1000>;
> +			interrupts = <0 71 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 19 1 &pmx0 1 20 1 &pmx0 2 21 1
> +					&pmx0 3 22 1 &pmx0 4 23 1 &pmx0 5 24 1
> +					&pmx0 6 25 1 &pmx0 7 26 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk7>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio8: gpio at fc80e000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80e000 0x1000>;
> +			interrupts = <0 72 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 27 1 &pmx0 1 28 1 &pmx0 2 29 1
> +					&pmx0 3 30 1 &pmx0 4 31 1 &pmx0 5 32 1
> +					&pmx0 6 33 1 &pmx0 7 34 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk8>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio9: gpio at fc80f000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc80f000 0x1000>;
> +			interrupts = <0 73 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 35 1 &pmx0 1 36 1 &pmx0 2 37 1
> +					&pmx0 3 38 1 &pmx0 4 39 1 &pmx0 5 40 1
> +					&pmx0 6 41 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk9>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio10: gpio at fc810000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc810000 0x1000>;
> +			interrupts = <0 74 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 2 43 1 &pmx0 3 44 1 &pmx0 4 45 1
> +					&pmx0 5 45 1 &pmx0 6 46 1 &pmx0 7 46 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk10>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio11: gpio at fc811000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc811000 0x1000>;
> +			interrupts = <0 75 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 47 1 &pmx0 1 47 1 &pmx0 2 47 1
> +					&pmx0 3 47 1 &pmx0 4 47 1 &pmx0 5 48 1
> +					&pmx0 6 49 1 &pmx0 7 49 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk11>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio12: gpio at fc812000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc812000 0x1000>;
> +			interrupts = <0 76 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 49 1 &pmx0 1 50 1 &pmx0 2 49 1
> +					&pmx0 3 49 1 &pmx0 4 51 1 &pmx0 5 51 1
> +					&pmx0 6 51 1 &pmx0 7 52 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk12>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio13: gpio at fc813000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc813000 0x1000>;
> +			interrupts = <0 77 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 51 1 &pmx0 1 51 1 &pmx0 2 53 1
> +					&pmx0 3 53 1 &pmx0 4 53 1 &pmx0 5 54 1
> +					&pmx0 6 55 1 &pmx0 7 56 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk13>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio14: gpio at fc814000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc814000 0x1000>;
> +			interrupts = <0 78 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 57 1 &pmx0 1 97 1 &pmx0 2 97 1
> +					&pmx0 3 58 1 &pmx0 4 59 1 &pmx0 5 60 1
> +					&pmx0 6 60 1 &pmx0 7 61 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk14>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio15: gpio at fc815000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc815000 0x1000>;
> +			interrupts = <0 79 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 61 1 &pmx0 1 62 1 &pmx0 2 62 1
> +					&pmx0 3 63 1 &pmx0 4 63 1 &pmx0 5 64 1
> +					&pmx0 6 64 1 &pmx0 7 65 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk15>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio16: gpio at fc816000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc816000 0x1000>;
> +			interrupts = <0 80 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 66 1 &pmx0 1 67 1 &pmx0 2 68 1
> +					&pmx0 3 69 1 &pmx0 4 70 1 &pmx0 5 71 1
> +					&pmx0 6 72 1 &pmx0 7 73 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk16>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio17: gpio at fc817000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc817000 0x1000>;
> +			interrupts = <0 81 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 74 1 &pmx0 1 75 1 &pmx0 2 76 1
> +					&pmx0 3 77 1 &pmx0 4 78 1 &pmx0 5 79 1
> +					&pmx0 6 80 1 &pmx0 7 81 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk17>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio18: gpio at fc818000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc818000 0x1000>;
> +			interrupts = <0 82 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 82 1 &pmx0 1 83 1 &pmx0 2 83 1
> +					&pmx0 3 84 1 &pmx0 4 84 1 &pmx0 5 85 1
> +					&pmx0 6 86 1 &pmx0 7 87 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk18>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio19: gpio at fc819000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc819000 0x1000>;
> +			interrupts = <0 83 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 87 1 &pmx0 1 87 1 &pmx0 2 88 1
> +					&pmx0 3 88 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk19>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio20: gpio at fc81a000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc81a000 0x1000>;
> +			interrupts = <0 84 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1
> +					&pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk20>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		gpio21: gpio at fc81b000 {
> +			compatible = "arm,pl061", "arm,primecell";
> +			reg = <0xfc81b000 0x1000>;
> +			interrupts = <0 85 0x4>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <	&pmx0 3 94 1 &pmx0 7 96 1>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +			clocks = <&gpioclk21>;
> +			clock-names = "apb_pclk";
> +		};
> +
> +		pmx0: pinmux at fc803000 {
> +			compatible = "pinctrl-single";
> +			reg = <0xfc803000 0x188>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			#gpio-range-cells = <3>;
> +			ranges;
> +
> +			pinctrl-single,register-width = <32>;
> +			pinctrl-single,function-mask = <7>;
> +			/* pin base, nr pins & gpio function */
> +			pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
> +						&range 12 1 0 &range 13 29 1
> +						&range 43 1 0 &range 44 49 1
> +						&range 94 1 1 &range 96 2 1>;
> +
> +			range: gpio-range {
> +				#pinctrl-single,gpio-range-cells = <3>;
> +			};
> +		};
> +
> +		pmx1: pinmux at fc803800 {
> +			compatible = "pinconf-single";
> +			reg = <0xfc803800 0x2dc>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +
> +			pinctrl-single,register-width = <32>;
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/hi4511.dts b/arch/arm/boot/dts/hi4511.dts
> new file mode 100644
> index 0000000..66ac03a
> --- /dev/null
> +++ b/arch/arm/boot/dts/hi4511.dts
> @@ -0,0 +1,648 @@
> +/*
> + *  Copyright (C) 2012-2013 Linaro Ltd.
> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  publishhed by the Free Software Foundation.
> + */
> +
> +/dts-v1/;
> +/include/ "hi3620.dtsi"
> +
> +/ {
> +	model = "Hisilicon Hi4511 Development Board";
> +	compatible = "hisilicon,hi3620-hi4511";
> +
> +	chosen {
> +		bootargs = "console=ttyAMA0,115200 root=/dev/ram0";
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x40000000 0x20000000>;
> +	};
> +
> +	amba {
> +		timer0: timer at fc800000 {
> +			status = "ok";
> +		};
> +
> +		uart0: uart at fcb00000 {	/* console */
> +			pinctrl-names = "default", "idle";
> +			pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>;
> +			pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>;
> +			status = "ok";
> +		};
> +
> +		uart1: uart at fcb01000 { /* modem */
> +			pinctrl-names = "default", "idle";
> +			pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>;
> +			pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>;
> +			status = "ok";
> +		};
> +
> +		uart2: uart at fcb02000 { /* audience */
> +			pinctrl-names = "default", "idle";
> +			pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>;
> +			pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>;
> +			status = "ok";
> +		};
> +
> +		uart3: uart at fcb03000 {
> +			pinctrl-names = "default", "idle";
> +			pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
> +			pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>;
> +			status = "ok";
> +		};
> +
> +		uart4: uart at fcb04000 {
> +			pinctrl-names = "default", "idle";
> +			pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>;
> +			pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>;
> +			status = "ok";
> +		};
> +
> +		pmx0: pinmux at fc803000 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&board_pmx_pins>;
> +
> +			board_pmx_pins: board_pmx_pins {
> +				pinctrl-single,pins = <
> +					0x008 0x0	/* GPIO -- eFUSE_DOUT */
> +					0x100 0x0	/* USIM_CLK & USIM_DATA (IOMG63) */
> +				>;
> +			};
> +			uart0_pmx_func: uart0_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0f0 0x0
> +					0x0f4 0x0	/* UART0_RX & UART0_TX */
> +				>;
> +			};
> +			uart0_pmx_idle: uart0_pmx_idle {
> +				pinctrl-single,pins = <
> +					/*0x0f0 0x1*/	/* UART0_CTS & UART0_RTS */
> +					0x0f4 0x1	/* UART0_RX & UART0_TX */
> +				>;
> +			};
> +			uart1_pmx_func: uart1_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0f8 0x0	/* UART1_CTS & UART1_RTS (IOMG61) */
> +					0x0fc 0x0	/* UART1_RX & UART1_TX (IOMG62) */
> +				>;
> +			};
> +			uart1_pmx_idle: uart1_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0f8 0x1	/* GPIO (IOMG61) */
> +					0x0fc 0x1	/* GPIO (IOMG62) */
> +				>;
> +			};
> +			uart2_pmx_func: uart2_pmx_func {
> +				pinctrl-single,pins = <
> +					0x104 0x2	/* UART2_RXD (IOMG96) */
> +					0x108 0x2	/* UART2_TXD (IOMG64) */
> +				>;
> +			};
> +			uart2_pmx_idle: uart2_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x104 0x1	/* GPIO (IOMG96) */
> +					0x108 0x1	/* GPIO (IOMG64) */
> +				>;
> +			};
> +			uart3_pmx_func: uart3_pmx_func {
> +				pinctrl-single,pins = <
> +					0x160 0x2	/* UART3_CTS & UART3_RTS (IOMG85) */
> +					0x164 0x2	/* UART3_RXD & UART3_TXD (IOMG86) */
> +				>;
> +			};
> +			uart3_pmx_idle: uart3_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x160 0x1	/* GPIO (IOMG85) */
> +					0x164 0x1	/* GPIO (IOMG86) */
> +				>;
> +			};
> +			uart4_pmx_func: uart4_pmx_func {
> +				pinctrl-single,pins = <
> +					0x168 0x0	/* UART4_CTS & UART4_RTS (IOMG87) */
> +					0x16c 0x0	/* UART4_RXD (IOMG88) */
> +					0x170 0x0	/* UART4_TXD (IOMG93) */
> +				>;
> +			};
> +			uart4_pmx_idle: uart4_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x168 0x1	/* GPIO (IOMG87) */
> +					0x16c 0x1	/* GPIO (IOMG88) */
> +					0x170 0x1	/* GPIO (IOMG93) */
> +				>;
> +			};
> +			i2c0_pmx_func: i2c0_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0b4 0x0	/* I2C0_SCL & I2C0_SDA (IOMG45) */
> +				>;
> +			};
> +			i2c0_pmx_idle: i2c0_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0b4 0x1	/* GPIO (IOMG45) */
> +				>;
> +			};
> +			i2c1_pmx_func: i2c1_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0b8 0x0	/* I2C1_SCL & I2C1_SDA (IOMG46) */
> +				>;
> +			};
> +			i2c1_pmx_idle: i2c1_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0b8 0x1	/* GPIO (IOMG46) */
> +				>;
> +			};
> +			i2c2_pmx_func: i2c2_pmx_func {
> +				pinctrl-single,pins = <
> +					0x068 0x0	/* I2C2_SCL (IOMG26) */
> +					0x06c 0x0	/* I2C2_SDA (IOMG27) */
> +				>;
> +			};
> +			i2c2_pmx_idle: i2c2_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x068 0x1	/* GPIO (IOMG26) */
> +					0x06c 0x1	/* GPIO (IOMG27) */
> +				>;
> +			};
> +			i2c3_pmx_func: i2c3_pmx_func {
> +				pinctrl-single,pins = <
> +					0x050 0x2	/* I2C3_SCL (IOMG20) */
> +					0x054 0x2	/* I2C3_SDA (IOMG21) */
> +				>;
> +			};
> +			i2c3_pmx_idle: i2c3_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x050 0x1	/* GPIO (IOMG20) */
> +					0x054 0x1	/* GPIO (IOMG21) */
> +				>;
> +			};
> +			spi0_pmx_func: spi0_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0d4 0x0	/* SPI0_CLK/SPI0_DI/SPI0_DO (IOMG53) */
> +					0x0d8 0x0	/* SPI0_CS0 (IOMG54) */
> +					0x0dc 0x0	/* SPI0_CS1 (IOMG55) */
> +					0x0e0 0x0	/* SPI0_CS2 (IOMG56) */
> +					0x0e4 0x0	/* SPI0_CS3 (IOMG57) */
> +				>;
> +			};
> +			spi0_pmx_idle: spi0_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0d4 0x1	/* GPIO (IOMG53) */
> +					0x0d8 0x1	/* GPIO (IOMG54) */
> +					0x0dc 0x1	/* GPIO (IOMG55) */
> +					0x0e0 0x1	/* GPIO (IOMG56) */
> +					0x0e4 0x1	/* GPIO (IOMG57) */
> +				>;
> +			};
> +			spi1_pmx_func: spi1_pmx_func {
> +				pinctrl-single,pins = <
> +					0x184 0x0	/* SPI1_CLK/SPI1_DI (IOMG98) */
> +					0x0e8 0x0	/* SPI1_DO (IOMG58) */
> +					0x0ec 0x0	/* SPI1_CS (IOMG95) */
> +				>;
> +			};
> +			spi1_pmx_idle: spi1_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x184 0x1	/* GPIO (IOMG98) */
> +					0x0e8 0x1	/* GPIO (IOMG58) */
> +					0x0ec 0x1	/* GPIO (IOMG95) */
> +				>;
> +			};
> +			kpc_pmx_func: kpc_pmx_func {
> +				pinctrl-single,pins = <
> +					0x12c 0x0	/* KEY_IN0 (IOMG73) */
> +					0x130 0x0	/* KEY_IN1 (IOMG74) */
> +					0x134 0x0	/* KEY_IN2 (IOMG75) */
> +					0x10c 0x0	/* KEY_OUT0 (IOMG65) */
> +					0x110 0x0	/* KEY_OUT1 (IOMG66) */
> +					0x114 0x0	/* KEY_OUT2 (IOMG67) */
> +				>;
> +			};
> +			kpc_pmx_idle: kpc_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x12c 0x1	/* GPIO (IOMG73) */
> +					0x130 0x1	/* GPIO (IOMG74) */
> +					0x134 0x1	/* GPIO (IOMG75) */
> +					0x10c 0x1	/* GPIO (IOMG65) */
> +					0x110 0x1	/* GPIO (IOMG66) */
> +					0x114 0x1	/* GPIO (IOMG67) */
> +				>;
> +			};
> +			gpio_key_func: gpio_key_func {
> +				pinctrl-single,pins = <
> +					0x10c 0x1	/* KEY_OUT0/GPIO (IOMG65) */
> +					0x130 0x1	/* KEY_IN1/GPIO (IOMG74) */
> +				>;
> +			};
> +			emmc_pmx_func: emmc_pmx_func {
> +				pinctrl-single,pins = <
> +					0x030 0x2	/* eMMC_CMD/eMMC_CLK (IOMG12) */
> +					0x018 0x0	/* NAND_CS3_N (IOMG6) */
> +					0x024 0x0	/* NAND_BUSY2_N (IOMG8) */
> +					0x028 0x0	/* NAND_BUSY3_N (IOMG9) */
> +					0x02c 0x2	/* eMMC_DATA[0:7] (IOMG10) */
> +				>;
> +			};
> +			emmc_pmx_idle: emmc_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x030 0x0	/* GPIO (IOMG12) */
> +					0x018 0x1	/* GPIO (IOMG6) */
> +					0x024 0x1	/* GPIO (IOMG8) */
> +					0x028 0x1	/* GPIO (IOMG9) */
> +					0x02c 0x1	/* GPIO (IOMG10) */
> +				>;
> +			};
> +			sd_pmx_func: sd_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0bc 0x0	/* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */
> +					0x0c0 0x0	/* SD_DATA3 (IOMG48) */
> +				>;
> +			};
> +			sd_pmx_idle: sd_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0bc 0x1	/* GPIO (IOMG47) */
> +					0x0c0 0x1	/* GPIO (IOMG48) */
> +				>;
> +			};
> +			nand_pmx_func: nand_pmx_func {
> +				pinctrl-single,pins = <
> +					0x00c 0x0	/* NAND_ALE/NAND_CLE/.../NAND_DATA[0:7] (IOMG3) */
> +					0x010 0x0	/* NAND_CS1_N (IOMG4) */
> +					0x014 0x0	/* NAND_CS2_N (IOMG5) */
> +					0x018 0x0	/* NAND_CS3_N (IOMG6) */
> +					0x01c 0x0	/* NAND_BUSY0_N (IOMG94) */
> +					0x020 0x0	/* NAND_BUSY1_N (IOMG7) */
> +					0x024 0x0	/* NAND_BUSY2_N (IOMG8) */
> +					0x028 0x0	/* NAND_BUSY3_N (IOMG9) */
> +					0x02c 0x0	/* NAND_DATA[8:15] (IOMG10) */
> +				>;
> +			};
> +			nand_pmx_idle: nand_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x00c 0x1	/* GPIO (IOMG3) */
> +					0x010 0x1	/* GPIO (IOMG4) */
> +					0x014 0x1	/* GPIO (IOMG5) */
> +					0x018 0x1	/* GPIO (IOMG6) */
> +					0x01c 0x1	/* GPIO (IOMG94) */
> +					0x020 0x1	/* GPIO (IOMG7) */
> +					0x024 0x1	/* GPIO (IOMG8) */
> +					0x028 0x1	/* GPIO (IOMG9) */
> +					0x02c 0x1	/* GPIO (IOMG10) */
> +				>;
> +			};
> +			sdio_pmx_func: sdio_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0c4 0x0	/* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */
> +				>;
> +			};
> +			sdio_pmx_idle: sdio_pmx_idle {
> +				pinctrl-single,pins = <
> +					0x0c4 0x1	/* GPIO (IOMG49) */
> +				>;
> +			};
> +			audio_out_pmx_func: audio_out_pmx_func {
> +				pinctrl-single,pins = <
> +					0x0f0 0x1	/* GPIO (IOMG59), audio spk & earphone */
> +				>;
> +			};
> +		};
> +
> +		pmx1: pinmux at fc803800 {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <	&board_pu_pins &board_pd_pins &board_pd_ps_pins
> +					&board_np_pins &board_ps_pins &kpc_cfg_func
> +					&audio_out_cfg_func>;
> +			board_pu_pins: board_pu_pins {
> +				pinctrl-single,pins = <
> +					0x014 0		/* GPIO_158 (IOCFG2) */
> +					0x018 0		/* GPIO_159 (IOCFG3) */
> +					0x01c 0		/* BOOT_MODE0 (IOCFG4) */
> +					0x020 0		/* BOOT_MODE1 (IOCFG5) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <1 1 0 1>;
> +			};
> +			board_pd_pins: board_pd_pins {
> +				pinctrl-single,pins = <
> +					0x038 0		/* eFUSE_DOUT (IOCFG11) */
> +					0x150 0		/* ISP_GPIO8 (IOCFG93) */
> +					0x154 0		/* ISP_GPIO9 (IOCFG94) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			board_pd_ps_pins: board_pd_ps_pins {
> +				pinctrl-single,pins = <
> +					0x2d8 0		/* CLK_OUT0 (IOCFG190) */
> +					0x004 0		/* PMU_SPI_DATA (IOCFG192) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			board_np_pins: board_np_pins {
> +				pinctrl-single,pins = <
> +					0x24c 0		/* KEYPAD_OUT7 (IOCFG155) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			board_ps_pins: board_ps_pins {
> +				pinctrl-single,pins = <
> +					0x000 0		/* PMU_SPI_CLK (IOCFG191) */
> +					0x008 0		/* PMU_SPI_CS_N (IOCFG193) */
> +				>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			uart0_cfg_func: uart0_cfg_func {
> +				pinctrl-single,pins = <
> +					0x208 0		/* UART0_RXD (IOCFG138) */
> +					0x20c 0		/* UART0_TXD (IOCFG139) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart0_cfg_idle: uart0_cfg_idle {
> +				pinctrl-single,pins = <
> +					0x208 0		/* UART0_RXD (IOCFG138) */
> +					0x20c 0		/* UART0_TXD (IOCFG139) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart1_cfg_func: uart1_cfg_func {
> +				pinctrl-single,pins = <
> +					0x210 0		/* UART1_CTS (IOCFG140) */
> +					0x214 0		/* UART1_RTS (IOCFG141) */
> +					0x218 0		/* UART1_RXD (IOCFG142) */
> +					0x21c 0		/* UART1_TXD (IOCFG143) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart1_cfg_idle: uart1_cfg_idle {
> +				pinctrl-single,pins = <
> +					0x210 0		/* UART1_CTS (IOCFG140) */
> +					0x214 0		/* UART1_RTS (IOCFG141) */
> +					0x218 0		/* UART1_RXD (IOCFG142) */
> +					0x21c 0		/* UART1_TXD (IOCFG143) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart2_cfg_func: uart2_cfg_func {
> +				pinctrl-single,pins = <
> +					0x220 0		/* UART2_CTS (IOCFG144) */
> +					0x224 0		/* UART2_RTS (IOCFG145) */
> +					0x228 0		/* UART2_RXD (IOCFG146) */
> +					0x22c 0		/* UART2_TXD (IOCFG147) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart2_cfg_idle: uart2_cfg_idle {
> +				pinctrl-single,pins = <
> +					0x220 0		/* GPIO (IOCFG144) */
> +					0x224 0		/* GPIO (IOCFG145) */
> +					0x228 0		/* GPIO (IOCFG146) */
> +					0x22c 0		/* GPIO (IOCFG147) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart3_cfg_func: uart3_cfg_func {
> +				pinctrl-single,pins = <
> +					0x294 0		/* UART3_CTS (IOCFG173) */
> +					0x298 0		/* UART3_RTS (IOCFG174) */
> +					0x29c 0		/* UART3_RXD (IOCFG175) */
> +					0x2a0 0		/* UART3_TXD (IOCFG176) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart3_cfg_idle: uart3_cfg_idle {
> +				pinctrl-single,pins = <
> +					0x294 0		/* UART3_CTS (IOCFG173) */
> +					0x298 0		/* UART3_RTS (IOCFG174) */
> +					0x29c 0		/* UART3_RXD (IOCFG175) */
> +					0x2a0 0		/* UART3_TXD (IOCFG176) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			uart4_cfg_func: uart4_cfg_func {
> +				pinctrl-single,pins = <
> +					0x2a4 0		/* UART4_CTS (IOCFG177) */
> +					0x2a8 0		/* UART4_RTS (IOCFG178) */
> +					0x2ac 0		/* UART4_RXD (IOCFG179) */
> +					0x2b0 0		/* UART4_TXD (IOCFG180) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			i2c0_cfg_func: i2c0_cfg_func {
> +				pinctrl-single,pins = <
> +					0x17c 0		/* I2C0_SCL (IOCFG103) */
> +					0x180 0		/* I2C0_SDA (IOCFG104) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			i2c1_cfg_func: i2c1_cfg_func {
> +				pinctrl-single,pins = <
> +					0x184 0		/* I2C1_SCL (IOCFG105) */
> +					0x188 0		/* I2C1_SDA (IOCFG106) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			i2c2_cfg_func: i2c2_cfg_func {
> +				pinctrl-single,pins = <
> +					0x118 0		/* I2C2_SCL (IOCFG79) */
> +					0x11c 0		/* I2C2_SDA (IOCFG80) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			i2c3_cfg_func: i2c3_cfg_func {
> +				pinctrl-single,pins = <
> +					0x100 0		/* I2C3_SCL (IOCFG73) */
> +					0x104 0		/* I2C3_SDA (IOCFG74) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			spi0_cfg_func1: spi0_cfg_func1 {
> +				pinctrl-single,pins = <
> +					0x1d4 0		/* SPI0_CLK (IOCFG125) */
> +					0x1d8 0		/* SPI0_DI (IOCFG126) */
> +					0x1dc 0		/* SPI0_DO (IOCFG127) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			spi0_cfg_func2: spi0_cfg_func2 {
> +				pinctrl-single,pins = <
> +					0x1e0 0		/* SPI0_CS0 (IOCFG128) */
> +					0x1e4 0		/* SPI0_CS1 (IOCFG129) */
> +					0x1e8 0		/* SPI0_CS2 (IOCFG130 */
> +					0x1ec 0		/* SPI0_CS3 (IOCFG131) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <1 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			spi1_cfg_func1: spi1_cfg_func1 {
> +				pinctrl-single,pins = <
> +					0x1f0 0		/* SPI1_CLK (IOCFG132) */
> +					0x1f4 0		/* SPI1_DI (IOCFG133) */
> +					0x1f8 0		/* SPI1_DO (IOCFG134) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			spi1_cfg_func2: spi1_cfg_func2 {
> +				pinctrl-single,pins = <
> +					0x1fc 0		/* SPI1_CS (IOCFG135) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <1 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			kpc_cfg_func: kpc_cfg_func {
> +				pinctrl-single,pins = <
> +					0x250 0		/* KEY_IN0 (IOCFG156) */
> +					0x254 0		/* KEY_IN1 (IOCFG157) */
> +					0x258 0		/* KEY_IN2 (IOCFG158) */
> +					0x230 0		/* KEY_OUT0 (IOCFG148) */
> +					0x234 0		/* KEY_OUT1 (IOCFG149) */
> +					0x238 0		/* KEY_OUT2 (IOCFG150) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +			emmc_cfg_func: emmc_cfg_func {
> +				pinctrl-single,pins = <
> +					0x0ac 0		/* eMMC_CMD (IOCFG40) */
> +					0x0b0 0		/* eMMC_CLK (IOCFG41) */
> +					0x058 0		/* NAND_CS3_N (IOCFG19) */
> +					0x064 0		/* NAND_BUSY2_N (IOCFG22) */
> +					0x068 0		/* NAND_BUSY3_N (IOCFG23) */
> +					0x08c 0		/* NAND_DATA8 (IOCFG32) */
> +					0x090 0		/* NAND_DATA9 (IOCFG33) */
> +					0x094 0		/* NAND_DATA10 (IOCFG34) */
> +					0x098 0		/* NAND_DATA11 (IOCFG35) */
> +					0x09c 0		/* NAND_DATA12 (IOCFG36) */
> +					0x0a0 0		/* NAND_DATA13 (IOCFG37) */
> +					0x0a4 0		/* NAND_DATA14 (IOCFG38) */
> +					0x0a8 0		/* NAND_DATA15 (IOCFG39) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <1 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			sd_cfg_func1: sd_cfg_func1 {
> +				pinctrl-single,pins = <
> +					0x18c 0		/* SD_CLK (IOCFG107) */
> +					0x190 0		/* SD_CMD (IOCFG108) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			sd_cfg_func2: sd_cfg_func2 {
> +				pinctrl-single,pins = <
> +					0x194 0		/* SD_DATA0 (IOCFG109) */
> +					0x198 0		/* SD_DATA1 (IOCFG110) */
> +					0x19c 0		/* SD_DATA2 (IOCFG111) */
> +					0x1a0 0		/* SD_DATA3 (IOCFG112) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x70 0xf0>;
> +			};
> +			nand_cfg_func1: nand_cfg_func1 {
> +				pinctrl-single,pins = <
> +					0x03c 0		/* NAND_ALE (IOCFG12) */
> +					0x040 0		/* NAND_CLE (IOCFG13) */
> +					0x06c 0		/* NAND_DATA0 (IOCFG24) */
> +					0x070 0		/* NAND_DATA1 (IOCFG25) */
> +					0x074 0		/* NAND_DATA2 (IOCFG26) */
> +					0x078 0		/* NAND_DATA3 (IOCFG27) */
> +					0x07c 0		/* NAND_DATA4 (IOCFG28) */
> +					0x080 0		/* NAND_DATA5 (IOCFG29) */
> +					0x084 0		/* NAND_DATA6 (IOCFG30) */
> +					0x088 0		/* NAND_DATA7 (IOCFG31) */
> +					0x08c 0		/* NAND_DATA8 (IOCFG32) */
> +					0x090 0		/* NAND_DATA9 (IOCFG33) */
> +					0x094 0		/* NAND_DATA10 (IOCFG34) */
> +					0x098 0		/* NAND_DATA11 (IOCFG35) */
> +					0x09c 0		/* NAND_DATA12 (IOCFG36) */
> +					0x0a0 0		/* NAND_DATA13 (IOCFG37) */
> +					0x0a4 0		/* NAND_DATA14 (IOCFG38) */
> +					0x0a8 0		/* NAND_DATA15 (IOCFG39) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			nand_cfg_func2: nand_cfg_func2 {
> +				pinctrl-single,pins = <
> +					0x044 0		/* NAND_RE_N (IOCFG14) */
> +					0x048 0		/* NAND_WE_N (IOCFG15) */
> +					0x04c 0		/* NAND_CS0_N (IOCFG16) */
> +					0x050 0		/* NAND_CS1_N (IOCFG17) */
> +					0x054 0		/* NAND_CS2_N (IOCFG18) */
> +					0x058 0		/* NAND_CS3_N (IOCFG19) */
> +					0x05c 0		/* NAND_BUSY0_N (IOCFG20) */
> +					0x060 0		/* NAND_BUSY1_N (IOCFG21) */
> +					0x064 0		/* NAND_BUSY2_N (IOCFG22) */
> +					0x068 0		/* NAND_BUSY3_N (IOCFG23) */
> +				>;
> +				pinctrl-single,bias-pulldown = <0 2 0 2>;
> +				pinctrl-single,bias-pullup = <1 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			sdio_cfg_func: sdio_cfg_func {
> +				pinctrl-single,pins = <
> +					0x1a4 0		/* SDIO0_CLK (IOCG113) */
> +					0x1a8 0		/* SDIO0_CMD (IOCG114) */
> +					0x1ac 0		/* SDIO0_DATA0 (IOCG115) */
> +					0x1b0 0		/* SDIO0_DATA1 (IOCG116) */
> +					0x1b4 0		/* SDIO0_DATA2 (IOCG117) */
> +					0x1b8 0		/* SDIO0_DATA3 (IOCG118) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +				pinctrl-single,drive-strength = <0x30 0xf0>;
> +			};
> +			audio_out_cfg_func: audio_out_cfg_func {
> +				pinctrl-single,pins = <
> +					0x200 0		/* GPIO (IOCFG136) */
> +					0x204 0		/* GPIO (IOCFG137) */
> +				>;
> +				pinctrl-single,bias-pulldown = <2 2 0 2>;
> +				pinctrl-single,bias-pullup = <0 1 0 1>;
> +			};
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		call {
> +			label = "call";
> +			gpios = <&gpio17 2 0>;
> +			linux,code = <169>;	/* KEY_PHONE */
> +		};
> +	};
> +};
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 2e67a27..59f9753 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -6,6 +6,7 @@ CONFIG_MACH_ARMADA_370=y
>  CONFIG_ARCH_SIRF=y
>  CONFIG_MACH_ARMADA_XP=y
>  CONFIG_ARCH_HIGHBANK=y
> +CONFIG_ARCH_HI3xxx=y
>  CONFIG_ARCH_SOCFPGA=y
>  CONFIG_ARCH_SUNXI=y
>  CONFIG_ARCH_WM8850=y
> -- 
> 1.8.1.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 with device tree
  2013-06-17 17:41   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-06-17 21:39     ` Olof Johansson
  0 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2013-06-17 21:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 17, 2013 at 07:41:30PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:56 Mon 17 Jun     , Haojian Zhuang wrote:
> > Enable Hisilicon Hi4511 development platform with device tree support.
> > 
> 
> please use macro for DT I'll review this end of the week
> 

1) What macro? Please consider how others are expected to read and understand
   your emails. Spending one minute on a reply at your end means many minutes
   saved in confusion and headscratching at the other end, among many people.

2) Please don't quote a 1900 line email just to add one line.


-Olof

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
@ 2013-06-17 21:50   ` Olof Johansson
  2013-06-25  3:50     ` Haojian Zhuang
  2013-07-01 19:06     ` Mark Brown
  2013-06-20 20:22   ` Mike Turquette
  1 sibling, 2 replies; 15+ messages in thread
From: Olof Johansson @ 2013-06-17 21:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

A once over mostly on the readability and some of the bindings. I'm presuming
that Mike Turquette will come in with a proper clock review, and probably merge
this through his tree.


-Olof

On Mon, Jun 17, 2013 at 04:56:13PM +0800, Haojian Zhuang wrote:
> Add clock support with device tree on Hisilicon SoC.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> Cc: Mike Turquette <mturquette@linaro.org>
> ---
>  .../devicetree/bindings/clock/hisilicon.txt        |  66 ++++
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/clk-hi3xxx.c                           | 414 +++++++++++++++++++++
>  3 files changed, 481 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
>  create mode 100644 drivers/clk/clk-hi3xxx.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
> new file mode 100644
> index 0000000..7f99805
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
> @@ -0,0 +1,66 @@
> +Device Tree Clock bindings for arch-hi3xxx
> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties for mux clocks:
> + - compatible : Shall be "hisilicon,hi3620-clk-mux".
> + - clocks : shall be the input parent clock phandle for the clock. This should
> +	be the reference clock.
> + - clock-output-names : shall be reference name.
> + - #clock-cells : from common clock binding; shall be set to 0.
> + - hisilicon,clkmux-reg : array of mux register offset & mask bits
> + - hisilicon,clkmux-table : array of mux select bits
> +
> +Required properties for Hi3620 gate clocks:
> + - compatible : Shall be "hisilicon,hi3620-clk-gate".
> + - clocks : shall be the input parent clock phandle for the clock. This should
> +	be the reference clock.
> + - clock-output-names : shall be reference name.
> + - #clock-cells : from common clock binding; shall be set to 0.
> + - hisilicon,hi3620-clkgate : array of enable register offset & enable bits
> + - hisilicon,hi3620-clkreset : array of reset register offset & enable bits
> +
> +Required properties for clock divider:
> + - compatible : Shall be "hisilicon,hi3620-clk-div".
> + - clocks : shall be the input parent clock phandle for the clock. This should
> +	be the reference clock.
> + - clock-output-names : shall be reference name.
> + - #clock-cells : from common clock binding; shall be set to 0.
> + - #hisilicon,clkdiv-table-cells : the number of parameters after phandle in
> +   hisilicon,clkdiv-table property.
> + - hisilicon,clkdiv-table : list of value that are used to configure clock

For a binding that is your own, you don't need to prefix the properties.
Prefixes are mostly used when adding new vendor-specific attributes to a common
binding.

> +   divider. They're value of phandle, index & divider value.
> + - hisilicon,clkdiv : array of divider register offset & mask bits.
> +
> +Required properties for gate clocks:
> + - compatible : Shall be "hisilicon,clk-gate".
> + - clocks : shall be the input parent clock phandle for the clock. This should
> +	be the reference clock.
> + - clock-output-names : shall be reference name.
> + - #clock-cells : from common clock binding; shall be set to 0.
> + - hisilicon,clkgate-inverted : bool value. True means that set-to-disable.
> +
> +For example:
> +	timclk1: clkgate at 38 {
> +		compatible = "hisilicon,clk-gate";
> +		#clock-cells = <0>;
> +		clocks = <&refclk_timer1>;
> +		clock-output-names = "timclk1";
> +		hisilicon,clkgate-inverted;
> +		hisilicon,clkgate = <0 18>;
> +	};
> +
> +	dtable: clkdiv at 0 {
> +		#hisilicon,clkdiv-table-cells = <2>;
> +	};
> +
> +	div_cfgaxi: clkdiv at 2 {
> +		compatible = "hisilicon,hi3620-clk-div";
> +		#clock-cells = <0>;
> +		clocks = <&div_shareaxi>;
> +		clock-output-names = "cfgAXI_div";
> +		hisilicon,clkdiv-table = <&dtable 0x01 2>;
> +		hisilicon,clkdiv = <0x100 0x60>;
> +	};
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 137d3e7..522e8d1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK)	+= clk-composite.o
>  # SoCs specific
>  obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835.o
>  obj-$(CONFIG_ARCH_NOMADIK)	+= clk-nomadik.o
> +obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3xxx.o
>  obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
>  obj-$(CONFIG_ARCH_MXS)		+= mxs/
>  obj-$(CONFIG_ARCH_SOCFPGA)	+= socfpga/
> diff --git a/drivers/clk/clk-hi3xxx.c b/drivers/clk/clk-hi3xxx.c
> new file mode 100644
> index 0000000..14c2f80
> --- /dev/null
> +++ b/drivers/clk/clk-hi3xxx.c
> @@ -0,0 +1,414 @@
> +/*
> + * Hisilicon clock driver
> + *
> + * Copyright (c) 2012-2013 Hisilicon Limited.
> + * Copyright (c) 2012-2013 Linaro Limited.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *	   Xin Li <li.xin@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk-private.h>
> +#include <linux/clkdev.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +
> +#define HI3620_DISABLE_OFF		0x4
> +#define HI3620_STATUS_OFF		0x8
> +
> +enum {
> +	HI3620_SCTRL,
> +	HI3XXX_MAX,
> +};
> +
> +struct hi3620_periclk {
> +	struct clk_hw	hw;
> +	void __iomem	*enable;	/* enable register */
> +	void __iomem	*reset;		/* reset register */
> +	u32		ebits;		/* bits in enable/disable register */
> +	u32		rbits;		/* bits in reset/unreset register */
> +	spinlock_t	*lock;
> +};
> +
> +struct hs_clk {
> +	void __iomem	*pmctrl;
> +	void __iomem	*sctrl;
> +	spinlock_t	lock;
> +};
> +
> +static void __iomem *hi3xxx_clk_base[HI3XXX_MAX];

This is a 1-entry array of pointers. What do you expect it to grow with in the
future? It's easier not adding extra complexity with the initial code; it will
just add more review comments to get stuck on. Such as the one below:

> +static DEFINE_SPINLOCK(hi3xxx_clk_lock);
> +
> +static const struct of_device_id hi3xxx_of_match[] = {
> +	{ .compatible = "hisilicon,sctrl", .data = (void *)HI3620_SCTRL, },
> +};

You need a terminating entry here. Also, what is this property and how it is
used? It's not included in the bindings above.

> +
> +static void __iomem __init *hi3xxx_init_clocks(struct device_node *np)
> +{
> +	struct device_node *parent;
> +	const struct of_device_id *match;
> +	void __iomem *ret = NULL;
> +	int i;
> +
> +	parent = of_get_parent(np);
> +	if (!parent)
> +		goto out;
> +	match = of_match_node(hi3xxx_of_match, parent);
> +	if (!match)
> +		goto out;

Please explain for someone reading this code why you're going up one level and
looking for the "hisilicon,sctrl" device here, and why that's needed.

Also, you should probably print some sort of error/warning here when the lookup
fails.

> +
> +	i = (unsigned int)match->data;
> +	switch (i) {
> +	case HI3620_SCTRL:
> +		if (!hi3xxx_clk_base[i]) {
> +			ret = of_iomap(parent, 0);
> +			WARN_ON(!ret);
> +			hi3xxx_clk_base[i] = ret;
> +		} else {
> +			ret = hi3xxx_clk_base[i];
> +		}

This is unnecessarily complicated. You can do:

		if (hi3xxx_clk_base[i])
			return hi3xxx_clk_base[i]
		ret = of_iomap()
		...

> +		break;
> +	default:
> +		goto out;
> +	}
> +out:
> +	return ret;
> +}



-Olof

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

* [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc
  2013-06-17  8:56 ` [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
@ 2013-06-17 21:51   ` Olof Johansson
  0 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2013-06-17 21:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 17, 2013 at 04:56:14PM +0800, Haojian Zhuang wrote:
> Support UART0 debug ll on hisilicon Hi3620 SoC.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Acked-by: Olof Johansson <olof@lixom.net>


-Olof

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

* [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree
  2013-06-17  8:56 ` [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree Haojian Zhuang
@ 2013-06-17 21:51   ` Olof Johansson
  0 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2013-06-17 21:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 17, 2013 at 04:56:15PM +0800, Haojian Zhuang wrote:
> Add board support with device tree for Hisilicon Hi36xx/Hi37xx platform.
> 
> Changelog:
> v3:
> 1. Remove .map_io() in DT machine descriptor. Since debug_ll_io_init()
> is called by default.
> 2. Remove .init_machine() in DT machine descriptor. Since
> of_platform_populate() is called by default in DT mode.
> 
> v2:
> 1. Remove .init_irq() in DT machine descriptor. Since irqchip_init()
> is called by default in DT mode.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Acked-by: Olof Johansson <olof@lixom.net>


-Olof

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

* [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 with device tree
  2013-06-17  8:56 ` [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 " Haojian Zhuang
  2013-06-17 17:41   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-06-17 22:05   ` Olof Johansson
  1 sibling, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2013-06-17 22:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Some comments below. I didn't research the history of reviews so some might
already have been pointed out and debated; apoligies if they have.

You should also post the device-tree bindings, in particular the clock ones
since they seem to be a bit different from what else we have seen so far, to
device-tree discuss and get them reviewed by Grant/Rob as well as Mike.


-Olof

On Mon, Jun 17, 2013 at 04:56:16PM +0800, Haojian Zhuang wrote:
> Enable Hisilicon Hi4511 development platform with device tree support.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  arch/arm/boot/dts/Makefile          |    1 +
>  arch/arm/boot/dts/hi3620.dtsi       | 1147 +++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/hi4511.dts        |  648 ++++++++++++++++++++
>  arch/arm/configs/multi_v7_defconfig |    1 +
>  4 files changed, 1797 insertions(+)
>  create mode 100644 arch/arm/boot/dts/hi3620.dtsi
>  create mode 100644 arch/arm/boot/dts/hi4511.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index f0895c5..216f983 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -58,6 +58,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
>  	exynos5250-smdk5250.dtb \
>  	exynos5250-snow.dtb \
>  	exynos5440-ssdk5440.dtb
> +dtb-$(CONFIG_ARCH_HI3xxx) += hi4511.dtb
>  dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
>  	ecx-2000.dtb
>  dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
> diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
> new file mode 100644
> index 0000000..1f0a4aa
> --- /dev/null
> +++ b/arch/arm/boot/dts/hi3620.dtsi
> @@ -0,0 +1,1147 @@
> +/*
> + * Hisilicon Ltd. Hi3620 SoC
> + *
> + * Copyright (C) 2012-2013 Hisilicon Ltd.
> + * Copyright (C) 2012-2013 Linaro Ltd.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * publishhed by the Free Software Foundation.
> + */
> +
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +		serial3 = &uart3;
> +		serial4 = &uart4;
> +	};

I would expect a cpus entry around here...?
And a #size-cells and #address-cells.

> +
> +	osc32k: osc at 0 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		clock-output-names = "osc32khz";
> +	};
> +	osc26m: osc at 1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +		clock-output-names = "osc26mhz";
> +	};
> +	pclk: clk at 0 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +		clock-output-names = "apb_pclk";
> +	};

These are not good names. There's nothing inherently addressable by them but
you still have unit addresses on them. Also, if they have an unit address @<x>,
then they need a reg property. It's probably better to give them unique names
(and not abbreviated). "clock-armpclk". Or something.

> +	pll_arm0: clk at 1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1600000000>;
> +		clock-output-names = "armpll0";
> +	};
> +	pll_arm1: clk at 2 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1600000000>;
> +		clock-output-names = "armpll1";
> +	};
> +	pll_peri: clk at 3 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1440000000>;
> +		clock-output-names = "armpll2";
> +	};
> +	pll_usb: clk at 4 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1440000000>;
> +		clock-output-names = "armpll3";
> +	};
> +	pll_hdmi: clk at 5 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1188000000>;
> +		clock-output-names = "armpll4";
> +	};
> +	pll_gpu: clk at 6 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <1300000000>;
> +		clock-output-names = "armpll5";
> +	};

Are these clocks really just there on the board, or are they provided from
a PMIC or similar? Even if you don't have a driver for that chip, describing
the hardware correctly now (with the exception of calling the clocks
fixed-clock) seems like a good idea.

> +
> +	amba {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "arm,amba-bus";
> +		interrupt-parent = <&intc>;
> +		ranges;
> +
> +		pmctrl: pmctrl at fca08000 {
> +			compatible = "hisilicon,pmctrl";
> +			reg = <0xfca08000 0x1000>;
> +		};

[...]

> +			dtable: dtable {
> +				#hisilicon,clkdiv-table-cells = <2>;

This definitely needs some review by the devicetree guys, Rob/Grant. It seems
like a quite unusual binding. What hardware does dtable represent?

> +			};
> +			div_shareaxi: div_shareaxi {
> +				compatible = "hisilicon,hi3620-clk-div";
> +				#clock-cells = <0>;
> +				clocks = <&rclk_shareAXI>;
> +				clock-output-names = "shareAXI_div";
> +				hisilicon,clkdiv-table = <
> +					&dtable 0 1 &dtable 1 2 &dtable 2 3 &dtable 3 4
> +					&dtable 4 5 &dtable 5 6 &dtable 6 7 &dtable 7 8
> +					&dtable 8 9 &dtable 9 10 &dtable 10 11 &dtable 11 12
> +					&dtable 12 13 &dtable 13 14 &dtable 14 15 &dtable 15 16
> +					&dtable 16 17 &dtable 17 18 &dtable 18 19 &dtable 19 20
> +					&dtable 20 21 &dtable 21 22 &dtable 22 23 &dtable 23 24
> +					&dtable 24 25 &dtable 25 26 &dtable 26 27 &dtable 27 28
> +					&dtable 28 29 &dtable 29 30 &dtable 30 31 &dtable 31 32>;
> +				/* divider register offset, mask */
> +				hisilicon,clkdiv = <0x100 0x1f>;
> +			};

> +
> +		l2: l2-cache {
> +			compatible = "arm,pl310-cache";
> +			reg = <0xfc10000 0x100000>;
> +			interrupts = <0 15 4>;
> +			cache-unified;
> +			cache-level = <2>;
> +		};

L2 is on amba?

> +
> +		intc: interrupt-controller at fc001000 {

It's common to use "gic" as the label instead.

> +			compatible = "arm,cortex-a9-gic";
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +			/* gic dist base, gic cpu base */
> +			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
> +		};
> +

[...]



-Olof

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
  2013-06-17 21:50   ` Olof Johansson
@ 2013-06-20 20:22   ` Mike Turquette
  2013-06-25  3:59     ` Haojian Zhuang
  1 sibling, 1 reply; 15+ messages in thread
From: Mike Turquette @ 2013-06-20 20:22 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Haojian Zhuang (2013-06-17 01:56:13)
> diff --git a/drivers/clk/clk-hi3xxx.c b/drivers/clk/clk-hi3xxx.c
> new file mode 100644
> index 0000000..14c2f80
> --- /dev/null
> +++ b/drivers/clk/clk-hi3xxx.c
> @@ -0,0 +1,414 @@
> +/*
> + * Hisilicon clock driver
> + *
> + * Copyright (c) 2012-2013 Hisilicon Limited.
> + * Copyright (c) 2012-2013 Linaro Limited.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *        Xin Li <li.xin@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk-private.h>

Please remove clk-private.h.

> +#include <linux/clkdev.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +
> +#define HI3620_DISABLE_OFF             0x4
> +#define HI3620_STATUS_OFF              0x8
> +
> +enum {
> +       HI3620_SCTRL,
> +       HI3XXX_MAX,
> +};
> +
> +struct hi3620_periclk {
> +       struct clk_hw   hw;
> +       void __iomem    *enable;        /* enable register */
> +       void __iomem    *reset;         /* reset register */
> +       u32             ebits;          /* bits in enable/disable register */
> +       u32             rbits;          /* bits in reset/unreset register */
> +       spinlock_t      *lock;
> +};
> +
> +struct hs_clk {
> +       void __iomem    *pmctrl;
> +       void __iomem    *sctrl;
> +       spinlock_t      lock;
> +};

I don't see struct hs_clk used anywhere.

> +
> +static void __iomem *hi3xxx_clk_base[HI3XXX_MAX];
> +
> +static DEFINE_SPINLOCK(hi3xxx_clk_lock);
> +
> +static const struct of_device_id hi3xxx_of_match[] = {
> +       { .compatible = "hisilicon,sctrl", .data = (void *)HI3620_SCTRL, },
> +};
> +
> +static void __iomem __init *hi3xxx_init_clocks(struct device_node *np)
> +{
> +       struct device_node *parent;
> +       const struct of_device_id *match;
> +       void __iomem *ret = NULL;
> +       int i;
> +
> +       parent = of_get_parent(np);
> +       if (!parent)
> +               goto out;
> +       match = of_match_node(hi3xxx_of_match, parent);
> +       if (!match)
> +               goto out;
> +
> +       i = (unsigned int)match->data;
> +       switch (i) {
> +       case HI3620_SCTRL:
> +               if (!hi3xxx_clk_base[i]) {
> +                       ret = of_iomap(parent, 0);
> +                       WARN_ON(!ret);
> +                       hi3xxx_clk_base[i] = ret;
> +               } else {
> +                       ret = hi3xxx_clk_base[i];
> +               }
> +               break;
> +       default:
> +               goto out;
> +       }
> +out:
> +       return ret;
> +}
> +
> +static int hi3620_clkgate_prepare(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       if (pclk->reset) {
> +               writel_relaxed(pclk->rbits, pclk->reset + HI3620_DISABLE_OFF);
> +               readl_relaxed(pclk->reset + HI3620_STATUS_OFF);
> +       }
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +       return 0;
> +}
> +
> +static int hi3620_clkgate_enable(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       writel_relaxed(pclk->ebits, pclk->enable);
> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +       return 0;
> +}
> +
> +static void hi3620_clkgate_disable(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +}
> +
> +static struct clk_ops hi3620_clkgate_ops = {
> +       .prepare        = hi3620_clkgate_prepare,
> +       .enable         = hi3620_clkgate_enable,
> +       .disable        = hi3620_clkgate_disable,

Missing .unprepare always worries me. What does your .prepare do?

> +};
> +
> +static void __init hi3620_clkgate_setup(struct device_node *np)
> +{
> +       struct hi3620_periclk *pclk;
> +       struct clk_init_data *init;
> +       struct clk *clk;
> +       const char *clk_name, *name, **parent_names;
> +       u32 rdata[2], gdata[2];
> +       void __iomem *base;
> +
> +       base = hi3xxx_init_clocks(np);
> +       if (!base)
> +               return;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,hi3620-clkgate",
> +                                      &gdata[0], 2))
> +               return;
> +
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +
> +       pclk = kzalloc(sizeof(*pclk), GFP_KERNEL);
> +       if (!pclk)
> +               goto err_pclk;
> +
> +       init = kzalloc(sizeof(*init), GFP_KERNEL);
> +       if (!init)
> +               goto err_init;
> +       init->name = kstrdup(clk_name, GFP_KERNEL);
> +       init->ops = &hi3620_clkgate_ops;
> +       init->flags = CLK_SET_RATE_PARENT;
> +       init->parent_names = parent_names;
> +       init->num_parents = 1;
> +
> +       if (!of_property_read_u32_array(np, "hisilicon,hi3620-clkreset",
> +                                       &rdata[0], 2)) {
> +               pclk->reset = base + rdata[0];
> +               pclk->rbits = rdata[1];
> +       }
> +       pclk->enable = base + gdata[0];
> +       pclk->ebits = gdata[1];
> +       pclk->lock = &hi3xxx_clk_lock;
> +       pclk->hw.init = init;
> +
> +       clk = clk_register(NULL, &pclk->hw);
> +       if (IS_ERR(clk))
> +               goto err_clk;
> +       if (!of_property_read_string(np, "clock-names", &name))
> +               clk_register_clkdev(clk, name, NULL);
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err_clk:
> +       kfree(init);
> +err_init:
> +       kfree(pclk);
> +err_pclk:
> +       kfree(parent_names);
> +}
> +CLK_OF_DECLARE(hi3620_gate, "hisilicon,hi3620-clk-gate", hi3620_clkgate_setup)
> +
> +static int __init hi3xxx_parse_mux(struct device_node *np,
> +                                  u8 *num_parents,
> +                                  u32 *table)
> +{
> +       int i, cnt, ret;
> +
> +       /* get the count of items in mux */
> +       for (i = 0, cnt = 0; ; i++, cnt++) {
> +               /* parent's #clock-cells property is always 0 */
> +               if (!of_parse_phandle(np, "clocks", i))
> +                       break;
> +       }
> +
> +       for (i = 0; i < cnt; i++) {
> +               if (!of_clk_get_parent_name(np, i))
> +                       return -ENOENT;
> +       }
> +       *num_parents = cnt;
> +       table = kzalloc(sizeof(u32 *) * cnt, GFP_KERNEL);
> +       if (!table)
> +               return -ENOMEM;
> +       ret = of_property_read_u32_array(np, "hisilicon,clkmux-table",
> +                                        table, cnt);
> +       if (ret)
> +               goto err;
> +       return 0;
> +err:
> +       kfree(table);
> +       return ret;
> +}
> +
> +static void __init clkmux_setup(struct device_node *np, int mode)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names = NULL;
> +       u32 rdata[2], mask, *table = NULL;
> +       u8 num_parents, shift, clk_mux_flags = 0;
> +       void __iomem *reg, *base;
> +       int i, ret;
> +
> +       base = hi3xxx_init_clocks(np);
> +       if (!base)
> +               return;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,clkmux-reg",
> +                                      &rdata[0], 2))
> +               return;
> +       ret = hi3xxx_parse_mux(np, &num_parents, table);
> +       if (ret)
> +               return;
> +
> +       parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
> +       if (!parent_names)
> +               goto err;
> +       for (i = 0; i < num_parents; i++)
> +               parent_names[i] = of_clk_get_parent_name(np, i);
> +
> +       reg = base + rdata[0];
> +       shift = ffs(rdata[1]) - 1;
> +       mask = rdata[1] >> shift;
> +       if (mode)
> +               clk_mux_flags = CLK_MUX_HIWORD_MASK;
> +       clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents,
> +                                    CLK_SET_RATE_PARENT, reg, shift, mask,
> +                                    clk_mux_flags, table, &hi3xxx_clk_lock);

It seems that you could use the basic mux-clock DT binding I posted.
This looks to do the same thing. CLK_MUX_HIWORD_MASK will need to be
added as a new property, but otherwise it should work.

> +       if (IS_ERR(clk))
> +               goto err_clk;
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +
> +       return;
> +err_clk:
> +       kfree(parent_names);
> +err:
> +       kfree(table);
> +}
> +
> +static void __init hi3620_clkmux_setup(struct device_node *np)
> +{
> +       clkmux_setup(np, 1);
> +}
> +CLK_OF_DECLARE(hi3620_mux, "hisilicon,hi3620-clk-mux", hi3620_clkmux_setup)
> +
> +static void __init hi3xxx_clkmux_setup(struct device_node *np)
> +{
> +       clkmux_setup(np, 0);
> +}
> +CLK_OF_DECLARE(hi3xxx_mux, "hisilicon,clk-mux", hi3xxx_clkmux_setup)
> +
> +static void __init hs_clkgate_setup(struct device_node *np)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names, *name;
> +       unsigned long flags = 0;
> +       u32 data[2];
> +       void __iomem *base;
> +
> +       base = hi3xxx_init_clocks(np);
> +       if (!base)
> +               return;
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,clkgate",
> +                                      &data[0], 2))
> +               return;
> +       if (of_property_read_bool(np, "hisilicon,clkgate-inverted"))
> +               flags = CLK_GATE_SET_TO_DISABLE;
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +
> +       clk = clk_register_gate(NULL, clk_name, parent_names[0], 0,
> +                               base + data[0], (u8)data[1], flags,
> +                               &hi3xxx_clk_lock);

Same here. Looks like it could use the basic gate-clock binding.

> +       if (IS_ERR(clk))
> +               goto err;
> +       if (!of_property_read_string(np, "clock-names", &name))
> +               clk_register_clkdev(clk, name, NULL);
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err:
> +       kfree(parent_names);
> +}
> +CLK_OF_DECLARE(hs_gate, "hisilicon,clk-gate", hs_clkgate_setup)
> +
> +void __init hi3620_clkdiv_setup(struct device_node *np)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names;
> +       struct clk_div_table *table;
> +       unsigned int table_num;
> +       int i;
> +       u32 data[2];
> +       u8 shift, width;
> +       const char *propname = "hisilicon,clkdiv-table";
> +       const char *cellname = "#hisilicon,clkdiv-table-cells";
> +       struct of_phandle_args div_table;
> +       void __iomem *reg, *base;
> +
> +       base = hi3xxx_init_clocks(np);
> +       if (!base)
> +               return;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,clkdiv",
> +                                      &data[0], 2))
> +               return;
> +
> +       /*process the div_table*/
> +       for (i = 0; ; i++) {
> +               if (of_parse_phandle_with_args(np, propname, cellname,
> +                                              i, &div_table))
> +                       break;
> +       }
> +
> +       /*table ends with <0, 0>, so plus one to table_num*/
> +       table_num = i + 1;
> +
> +       table = kzalloc(sizeof(struct clk_div_table) * table_num, GFP_KERNEL);
> +       if (!table)
> +               return ;
> +
> +       for (i = 0; ; i++) {
> +               if (of_parse_phandle_with_args(np, propname, cellname,
> +                                              i, &div_table))
> +                       break;
> +
> +               table[i].val = div_table.args[0];
> +               table[i].div = div_table.args[1];
> +       }
> +
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               goto err_par;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +       reg = base + data[0];
> +       shift = ffs(data[1]) - 1;
> +       width = fls(data[1]) - ffs(data[1]) + 1;
> +       clk = clk_register_divider_table(NULL, clk_name, parent_names[0], 0,
> +                                        reg, shift, width,
> +                                        CLK_DIVIDER_HIWORD_MASK,
> +                                        table, &hi3xxx_clk_lock);

This also could use the basic divider-clock binding. I'll need to see if
the table parsing is the same. Again the HIWORD_MASK flag must be added
as a property.

Regards,
Mike

> +       if (IS_ERR(clk))
> +               goto err_clk;
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err_clk:
> +       kfree(parent_names);
> +err_par:
> +       kfree(table);
> +}
> +CLK_OF_DECLARE(hi3620_div, "hisilicon,hi3620-clk-div", hi3620_clkdiv_setup)
> -- 
> 1.8.1.2

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-17 21:50   ` Olof Johansson
@ 2013-06-25  3:50     ` Haojian Zhuang
  2013-07-01 19:06     ` Mark Brown
  1 sibling, 0 replies; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-25  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 18 June 2013 05:50, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
> A once over mostly on the readability and some of the bindings. I'm presuming
> that Mike Turquette will come in with a proper clock review, and probably merge
> this through his tree.
>
>
> -Olof
>
> On Mon, Jun 17, 2013 at 04:56:13PM +0800, Haojian Zhuang wrote:
>> Add clock support with device tree on Hisilicon SoC.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> Cc: Mike Turquette <mturquette@linaro.org>
>> ---
>>  .../devicetree/bindings/clock/hisilicon.txt        |  66 ++++
>>  drivers/clk/Makefile                               |   1 +
>>  drivers/clk/clk-hi3xxx.c                           | 414 +++++++++++++++++++++
>>  3 files changed, 481 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
>>  create mode 100644 drivers/clk/clk-hi3xxx.c
>>
>> diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
>> new file mode 100644
>> index 0000000..7f99805
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
>> @@ -0,0 +1,66 @@
>> +Device Tree Clock bindings for arch-hi3xxx
>> +
>> +This binding uses the common clock binding[1].
>> +
>> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
>> +
>> +Required properties for mux clocks:
>> + - compatible : Shall be "hisilicon,hi3620-clk-mux".
>> + - clocks : shall be the input parent clock phandle for the clock. This should
>> +     be the reference clock.
>> + - clock-output-names : shall be reference name.
>> + - #clock-cells : from common clock binding; shall be set to 0.
>> + - hisilicon,clkmux-reg : array of mux register offset & mask bits
>> + - hisilicon,clkmux-table : array of mux select bits
>> +
>> +Required properties for Hi3620 gate clocks:
>> + - compatible : Shall be "hisilicon,hi3620-clk-gate".
>> + - clocks : shall be the input parent clock phandle for the clock. This should
>> +     be the reference clock.
>> + - clock-output-names : shall be reference name.
>> + - #clock-cells : from common clock binding; shall be set to 0.
>> + - hisilicon,hi3620-clkgate : array of enable register offset & enable bits
>> + - hisilicon,hi3620-clkreset : array of reset register offset & enable bits
>> +
>> +Required properties for clock divider:
>> + - compatible : Shall be "hisilicon,hi3620-clk-div".
>> + - clocks : shall be the input parent clock phandle for the clock. This should
>> +     be the reference clock.
>> + - clock-output-names : shall be reference name.
>> + - #clock-cells : from common clock binding; shall be set to 0.
>> + - #hisilicon,clkdiv-table-cells : the number of parameters after phandle in
>> +   hisilicon,clkdiv-table property.
>> + - hisilicon,clkdiv-table : list of value that are used to configure clock
>
> For a binding that is your own, you don't need to prefix the properties.
> Prefixes are mostly used when adding new vendor-specific attributes to a common
> binding.

OK.
>
>> +   divider. They're value of phandle, index & divider value.
>> + - hisilicon,clkdiv : array of divider register offset & mask bits.
>> +
>> +Required properties for gate clocks:
>> + - compatible : Shall be "hisilicon,clk-gate".
>> + - clocks : shall be the input parent clock phandle for the clock. This should
>> +     be the reference clock.
>> + - clock-output-names : shall be reference name.
>> + - #clock-cells : from common clock binding; shall be set to 0.
>> + - hisilicon,clkgate-inverted : bool value. True means that set-to-disable.
>> +
>> +For example:
>> +     timclk1: clkgate at 38 {
>> +             compatible = "hisilicon,clk-gate";
>> +             #clock-cells = <0>;
>> +             clocks = <&refclk_timer1>;
>> +             clock-output-names = "timclk1";
>> +             hisilicon,clkgate-inverted;
>> +             hisilicon,clkgate = <0 18>;
>> +     };
>> +
>> +     dtable: clkdiv at 0 {
>> +             #hisilicon,clkdiv-table-cells = <2>;
>> +     };
>> +
>> +     div_cfgaxi: clkdiv at 2 {
>> +             compatible = "hisilicon,hi3620-clk-div";
>> +             #clock-cells = <0>;
>> +             clocks = <&div_shareaxi>;
>> +             clock-output-names = "cfgAXI_div";
>> +             hisilicon,clkdiv-table = <&dtable 0x01 2>;
>> +             hisilicon,clkdiv = <0x100 0x60>;
>> +     };
>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>> index 137d3e7..522e8d1 100644
>> --- a/drivers/clk/Makefile
>> +++ b/drivers/clk/Makefile
>> @@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK)    += clk-composite.o
>>  # SoCs specific
>>  obj-$(CONFIG_ARCH_BCM2835)   += clk-bcm2835.o
>>  obj-$(CONFIG_ARCH_NOMADIK)   += clk-nomadik.o
>> +obj-$(CONFIG_ARCH_HI3xxx)    += clk-hi3xxx.o
>>  obj-$(CONFIG_ARCH_HIGHBANK)  += clk-highbank.o
>>  obj-$(CONFIG_ARCH_MXS)               += mxs/
>>  obj-$(CONFIG_ARCH_SOCFPGA)   += socfpga/
>> diff --git a/drivers/clk/clk-hi3xxx.c b/drivers/clk/clk-hi3xxx.c
>> new file mode 100644
>> index 0000000..14c2f80
>> --- /dev/null
>> +++ b/drivers/clk/clk-hi3xxx.c
>> @@ -0,0 +1,414 @@
>> +/*
>> + * Hisilicon clock driver
>> + *
>> + * Copyright (c) 2012-2013 Hisilicon Limited.
>> + * Copyright (c) 2012-2013 Linaro Limited.
>> + *
>> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> + *      Xin Li <li.xin@linaro.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clk-private.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/clk.h>
>> +
>> +#define HI3620_DISABLE_OFF           0x4
>> +#define HI3620_STATUS_OFF            0x8
>> +
>> +enum {
>> +     HI3620_SCTRL,
>> +     HI3XXX_MAX,
>> +};
>> +
>> +struct hi3620_periclk {
>> +     struct clk_hw   hw;
>> +     void __iomem    *enable;        /* enable register */
>> +     void __iomem    *reset;         /* reset register */
>> +     u32             ebits;          /* bits in enable/disable register */
>> +     u32             rbits;          /* bits in reset/unreset register */
>> +     spinlock_t      *lock;
>> +};
>> +
>> +struct hs_clk {
>> +     void __iomem    *pmctrl;
>> +     void __iomem    *sctrl;
>> +     spinlock_t      lock;
>> +};
>> +
>> +static void __iomem *hi3xxx_clk_base[HI3XXX_MAX];
>
> This is a 1-entry array of pointers. What do you expect it to grow with in the
> future? It's easier not adding extra complexity with the initial code; it will
> just add more review comments to get stuck on. Such as the one below:
>
Clock registers exists in some components, such as System Controller,
graphics frame Controller, and so on. It means that I'll append new clock
nodes in this array in the future, such as EDC (graphic frame Controller).

Since the framebuffer driver isn't fully ready, I don't want to add these clocks
in this driver at this time.

>> +static DEFINE_SPINLOCK(hi3xxx_clk_lock);
>> +
>> +static const struct of_device_id hi3xxx_of_match[] = {
>> +     { .compatible = "hisilicon,sctrl", .data = (void *)HI3620_SCTRL, },
>> +};
>
> You need a terminating entry here. Also, what is this property and how it is
> used? It's not included in the bindings above.

Yes, it'll be appended in the future.
>
>> +
>> +static void __iomem __init *hi3xxx_init_clocks(struct device_node *np)
>> +{
>> +     struct device_node *parent;
>> +     const struct of_device_id *match;
>> +     void __iomem *ret = NULL;
>> +     int i;
>> +
>> +     parent = of_get_parent(np);
>> +     if (!parent)
>> +             goto out;
>> +     match = of_match_node(hi3xxx_of_match, parent);
>> +     if (!match)
>> +             goto out;
>
> Please explain for someone reading this code why you're going up one level and
> looking for the "hisilicon,sctrl" device here, and why that's needed.
>

Since those clock registers exist in some components, it needs to map those
register mapping. When it's mapped, the base of io mapping could be saved
in the hi3xxx_clk_base[] array.

If it's already mapped, we only need to access the saved address.

> Also, you should probably print some sort of error/warning here when the lookup
> fails.
>

OK. I'll append the warning/error information.

>> +
>> +     i = (unsigned int)match->data;
>> +     switch (i) {
>> +     case HI3620_SCTRL:
>> +             if (!hi3xxx_clk_base[i]) {
>> +                     ret = of_iomap(parent, 0);
>> +                     WARN_ON(!ret);
>> +                     hi3xxx_clk_base[i] = ret;
>> +             } else {
>> +                     ret = hi3xxx_clk_base[i];
>> +             }
>
> This is unnecessarily complicated. You can do:
>
>                 if (hi3xxx_clk_base[i])
>                         return hi3xxx_clk_base[i]
>                 ret = of_iomap()
>                 ...
>
OK

>> +             break;
>> +     default:
>> +             goto out;
>> +     }
>> +out:
>> +     return ret;
>> +}
>
>
>
> -Olof

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-20 20:22   ` Mike Turquette
@ 2013-06-25  3:59     ` Haojian Zhuang
  0 siblings, 0 replies; 15+ messages in thread
From: Haojian Zhuang @ 2013-06-25  3:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 June 2013 04:22, Mike Turquette <mturquette@linaro.org> wrote:
> Quoting Haojian Zhuang (2013-06-17 01:56:13)
>> diff --git a/drivers/clk/clk-hi3xxx.c b/drivers/clk/clk-hi3xxx.c
>> new file mode 100644
>> index 0000000..14c2f80
>> --- /dev/null
>> +++ b/drivers/clk/clk-hi3xxx.c
>> @@ -0,0 +1,414 @@
>> +/*
>> + * Hisilicon clock driver
>> + *
>> + * Copyright (c) 2012-2013 Hisilicon Limited.
>> + * Copyright (c) 2012-2013 Linaro Limited.
>> + *
>> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> + *        Xin Li <li.xin@linaro.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clk-private.h>
>
> Please remove clk-private.h.
>
>> +#include <linux/clkdev.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/clk.h>
>> +
>> +#define HI3620_DISABLE_OFF             0x4
>> +#define HI3620_STATUS_OFF              0x8
>> +
>> +enum {
>> +       HI3620_SCTRL,
>> +       HI3XXX_MAX,
>> +};
>> +
>> +struct hi3620_periclk {
>> +       struct clk_hw   hw;
>> +       void __iomem    *enable;        /* enable register */
>> +       void __iomem    *reset;         /* reset register */
>> +       u32             ebits;          /* bits in enable/disable register */
>> +       u32             rbits;          /* bits in reset/unreset register */
>> +       spinlock_t      *lock;
>> +};
>> +
>> +struct hs_clk {
>> +       void __iomem    *pmctrl;
>> +       void __iomem    *sctrl;
>> +       spinlock_t      lock;
>> +};
>
> I don't see struct hs_clk used anywhere.
>
Oh, I forgot to delete it. This structure is obsolete.

>> +
>> +static void __iomem *hi3xxx_clk_base[HI3XXX_MAX];
>> +
>> +static DEFINE_SPINLOCK(hi3xxx_clk_lock);
>> +
>> +static const struct of_device_id hi3xxx_of_match[] = {
>> +       { .compatible = "hisilicon,sctrl", .data = (void *)HI3620_SCTRL, },
>> +};
>> +
>> +static void __iomem __init *hi3xxx_init_clocks(struct device_node *np)
>> +{
>> +       struct device_node *parent;
>> +       const struct of_device_id *match;
>> +       void __iomem *ret = NULL;
>> +       int i;
>> +
>> +       parent = of_get_parent(np);
>> +       if (!parent)
>> +               goto out;
>> +       match = of_match_node(hi3xxx_of_match, parent);
>> +       if (!match)
>> +               goto out;
>> +
>> +       i = (unsigned int)match->data;
>> +       switch (i) {
>> +       case HI3620_SCTRL:
>> +               if (!hi3xxx_clk_base[i]) {
>> +                       ret = of_iomap(parent, 0);
>> +                       WARN_ON(!ret);
>> +                       hi3xxx_clk_base[i] = ret;
>> +               } else {
>> +                       ret = hi3xxx_clk_base[i];
>> +               }
>> +               break;
>> +       default:
>> +               goto out;
>> +       }
>> +out:
>> +       return ret;
>> +}
>> +
>> +static int hi3620_clkgate_prepare(struct clk_hw *hw)
>> +{
>> +       struct hi3620_periclk *pclk;
>> +       unsigned long flags = 0;
>> +
>> +       pclk = container_of(hw, struct hi3620_periclk, hw);
>> +
>> +       if (pclk->lock)
>> +               spin_lock_irqsave(pclk->lock, flags);
>> +       if (pclk->reset) {
>> +               writel_relaxed(pclk->rbits, pclk->reset + HI3620_DISABLE_OFF);
>> +               readl_relaxed(pclk->reset + HI3620_STATUS_OFF);
>> +       }
>> +       if (pclk->lock)
>> +               spin_unlock_irqrestore(pclk->lock, flags);
>> +       return 0;
>> +}
>> +
>> +static int hi3620_clkgate_enable(struct clk_hw *hw)
>> +{
>> +       struct hi3620_periclk *pclk;
>> +       unsigned long flags = 0;
>> +
>> +       pclk = container_of(hw, struct hi3620_periclk, hw);
>> +       if (pclk->lock)
>> +               spin_lock_irqsave(pclk->lock, flags);
>> +       writel_relaxed(pclk->ebits, pclk->enable);
>> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
>> +       if (pclk->lock)
>> +               spin_unlock_irqrestore(pclk->lock, flags);
>> +       return 0;
>> +}
>> +
>> +static void hi3620_clkgate_disable(struct clk_hw *hw)
>> +{
>> +       struct hi3620_periclk *pclk;
>> +       unsigned long flags = 0;
>> +
>> +       pclk = container_of(hw, struct hi3620_periclk, hw);
>> +       if (pclk->lock)
>> +               spin_lock_irqsave(pclk->lock, flags);
>> +       writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
>> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
>> +       if (pclk->lock)
>> +               spin_unlock_irqrestore(pclk->lock, flags);
>> +}
>> +
>> +static struct clk_ops hi3620_clkgate_ops = {
>> +       .prepare        = hi3620_clkgate_prepare,
>> +       .enable         = hi3620_clkgate_enable,
>> +       .disable        = hi3620_clkgate_disable,
>
> Missing .unprepare always worries me. What does your .prepare do?

Resetting clock is implemented in .prepare().

>
>> +};
>> +
>> +static void __init hi3620_clkgate_setup(struct device_node *np)
>> +{
>> +       struct hi3620_periclk *pclk;
>> +       struct clk_init_data *init;
>> +       struct clk *clk;
>> +       const char *clk_name, *name, **parent_names;
>> +       u32 rdata[2], gdata[2];
>> +       void __iomem *base;
>> +
>> +       base = hi3xxx_init_clocks(np);
>> +       if (!base)
>> +               return;
>> +
>> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
>> +               return;
>> +       if (of_property_read_u32_array(np, "hisilicon,hi3620-clkgate",
>> +                                      &gdata[0], 2))
>> +               return;
>> +
>> +       /* gate only has the fixed parent */
>> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
>> +       if (!parent_names)
>> +               return;
>> +       parent_names[0] = of_clk_get_parent_name(np, 0);
>> +
>> +       pclk = kzalloc(sizeof(*pclk), GFP_KERNEL);
>> +       if (!pclk)
>> +               goto err_pclk;
>> +
>> +       init = kzalloc(sizeof(*init), GFP_KERNEL);
>> +       if (!init)
>> +               goto err_init;
>> +       init->name = kstrdup(clk_name, GFP_KERNEL);
>> +       init->ops = &hi3620_clkgate_ops;
>> +       init->flags = CLK_SET_RATE_PARENT;
>> +       init->parent_names = parent_names;
>> +       init->num_parents = 1;
>> +
>> +       if (!of_property_read_u32_array(np, "hisilicon,hi3620-clkreset",
>> +                                       &rdata[0], 2)) {
>> +               pclk->reset = base + rdata[0];
>> +               pclk->rbits = rdata[1];
>> +       }
>> +       pclk->enable = base + gdata[0];
>> +       pclk->ebits = gdata[1];
>> +       pclk->lock = &hi3xxx_clk_lock;
>> +       pclk->hw.init = init;
>> +
>> +       clk = clk_register(NULL, &pclk->hw);
>> +       if (IS_ERR(clk))
>> +               goto err_clk;
>> +       if (!of_property_read_string(np, "clock-names", &name))
>> +               clk_register_clkdev(clk, name, NULL);
>> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
>> +       return;
>> +err_clk:
>> +       kfree(init);
>> +err_init:
>> +       kfree(pclk);
>> +err_pclk:
>> +       kfree(parent_names);
>> +}
>> +CLK_OF_DECLARE(hi3620_gate, "hisilicon,hi3620-clk-gate", hi3620_clkgate_setup)
>> +
>> +static int __init hi3xxx_parse_mux(struct device_node *np,
>> +                                  u8 *num_parents,
>> +                                  u32 *table)
>> +{
>> +       int i, cnt, ret;
>> +
>> +       /* get the count of items in mux */
>> +       for (i = 0, cnt = 0; ; i++, cnt++) {
>> +               /* parent's #clock-cells property is always 0 */
>> +               if (!of_parse_phandle(np, "clocks", i))
>> +                       break;
>> +       }
>> +
>> +       for (i = 0; i < cnt; i++) {
>> +               if (!of_clk_get_parent_name(np, i))
>> +                       return -ENOENT;
>> +       }
>> +       *num_parents = cnt;
>> +       table = kzalloc(sizeof(u32 *) * cnt, GFP_KERNEL);
>> +       if (!table)
>> +               return -ENOMEM;
>> +       ret = of_property_read_u32_array(np, "hisilicon,clkmux-table",
>> +                                        table, cnt);
>> +       if (ret)
>> +               goto err;
>> +       return 0;
>> +err:
>> +       kfree(table);
>> +       return ret;
>> +}
>> +
>> +static void __init clkmux_setup(struct device_node *np, int mode)
>> +{
>> +       struct clk *clk;
>> +       const char *clk_name, **parent_names = NULL;
>> +       u32 rdata[2], mask, *table = NULL;
>> +       u8 num_parents, shift, clk_mux_flags = 0;
>> +       void __iomem *reg, *base;
>> +       int i, ret;
>> +
>> +       base = hi3xxx_init_clocks(np);
>> +       if (!base)
>> +               return;
>> +
>> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
>> +               return;
>> +       if (of_property_read_u32_array(np, "hisilicon,clkmux-reg",
>> +                                      &rdata[0], 2))
>> +               return;
>> +       ret = hi3xxx_parse_mux(np, &num_parents, table);
>> +       if (ret)
>> +               return;
>> +
>> +       parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
>> +       if (!parent_names)
>> +               goto err;
>> +       for (i = 0; i < num_parents; i++)
>> +               parent_names[i] = of_clk_get_parent_name(np, i);
>> +
>> +       reg = base + rdata[0];
>> +       shift = ffs(rdata[1]) - 1;
>> +       mask = rdata[1] >> shift;
>> +       if (mode)
>> +               clk_mux_flags = CLK_MUX_HIWORD_MASK;
>> +       clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents,
>> +                                    CLK_SET_RATE_PARENT, reg, shift, mask,
>> +                                    clk_mux_flags, table, &hi3xxx_clk_lock);
>
> It seems that you could use the basic mux-clock DT binding I posted.
> This looks to do the same thing. CLK_MUX_HIWORD_MASK will need to be
> added as a new property, but otherwise it should work.

OK
>
>> +       if (IS_ERR(clk))
>> +               goto err_clk;
>> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
>> +
>> +       return;
>> +err_clk:
>> +       kfree(parent_names);
>> +err:
>> +       kfree(table);
>> +}
>> +
>> +static void __init hi3620_clkmux_setup(struct device_node *np)
>> +{
>> +       clkmux_setup(np, 1);
>> +}
>> +CLK_OF_DECLARE(hi3620_mux, "hisilicon,hi3620-clk-mux", hi3620_clkmux_setup)
>> +
>> +static void __init hi3xxx_clkmux_setup(struct device_node *np)
>> +{
>> +       clkmux_setup(np, 0);
>> +}
>> +CLK_OF_DECLARE(hi3xxx_mux, "hisilicon,clk-mux", hi3xxx_clkmux_setup)
>> +
>> +static void __init hs_clkgate_setup(struct device_node *np)
>> +{
>> +       struct clk *clk;
>> +       const char *clk_name, **parent_names, *name;
>> +       unsigned long flags = 0;
>> +       u32 data[2];
>> +       void __iomem *base;
>> +
>> +       base = hi3xxx_init_clocks(np);
>> +       if (!base)
>> +               return;
>> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
>> +               return;
>> +       if (of_property_read_u32_array(np, "hisilicon,clkgate",
>> +                                      &data[0], 2))
>> +               return;
>> +       if (of_property_read_bool(np, "hisilicon,clkgate-inverted"))
>> +               flags = CLK_GATE_SET_TO_DISABLE;
>> +       /* gate only has the fixed parent */
>> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
>> +       if (!parent_names)
>> +               return;
>> +       parent_names[0] = of_clk_get_parent_name(np, 0);
>> +
>> +       clk = clk_register_gate(NULL, clk_name, parent_names[0], 0,
>> +                               base + data[0], (u8)data[1], flags,
>> +                               &hi3xxx_clk_lock);
>
> Same here. Looks like it could use the basic gate-clock binding.
>
OK

>> +       if (IS_ERR(clk))
>> +               goto err;
>> +       if (!of_property_read_string(np, "clock-names", &name))
>> +               clk_register_clkdev(clk, name, NULL);
>> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
>> +       return;
>> +err:
>> +       kfree(parent_names);
>> +}
>> +CLK_OF_DECLARE(hs_gate, "hisilicon,clk-gate", hs_clkgate_setup)
>> +
>> +void __init hi3620_clkdiv_setup(struct device_node *np)
>> +{
>> +       struct clk *clk;
>> +       const char *clk_name, **parent_names;
>> +       struct clk_div_table *table;
>> +       unsigned int table_num;
>> +       int i;
>> +       u32 data[2];
>> +       u8 shift, width;
>> +       const char *propname = "hisilicon,clkdiv-table";
>> +       const char *cellname = "#hisilicon,clkdiv-table-cells";
>> +       struct of_phandle_args div_table;
>> +       void __iomem *reg, *base;
>> +
>> +       base = hi3xxx_init_clocks(np);
>> +       if (!base)
>> +               return;
>> +
>> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
>> +               return;
>> +       if (of_property_read_u32_array(np, "hisilicon,clkdiv",
>> +                                      &data[0], 2))
>> +               return;
>> +
>> +       /*process the div_table*/
>> +       for (i = 0; ; i++) {
>> +               if (of_parse_phandle_with_args(np, propname, cellname,
>> +                                              i, &div_table))
>> +                       break;
>> +       }
>> +
>> +       /*table ends with <0, 0>, so plus one to table_num*/
>> +       table_num = i + 1;
>> +
>> +       table = kzalloc(sizeof(struct clk_div_table) * table_num, GFP_KERNEL);
>> +       if (!table)
>> +               return ;
>> +
>> +       for (i = 0; ; i++) {
>> +               if (of_parse_phandle_with_args(np, propname, cellname,
>> +                                              i, &div_table))
>> +                       break;
>> +
>> +               table[i].val = div_table.args[0];
>> +               table[i].div = div_table.args[1];
>> +       }
>> +
>> +       /* gate only has the fixed parent */
>> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
>> +       if (!parent_names)
>> +               goto err_par;
>> +       parent_names[0] = of_clk_get_parent_name(np, 0);
>> +       reg = base + data[0];
>> +       shift = ffs(data[1]) - 1;
>> +       width = fls(data[1]) - ffs(data[1]) + 1;
>> +       clk = clk_register_divider_table(NULL, clk_name, parent_names[0], 0,
>> +                                        reg, shift, width,
>> +                                        CLK_DIVIDER_HIWORD_MASK,
>> +                                        table, &hi3xxx_clk_lock);
>
> This also could use the basic divider-clock binding. I'll need to see if
> the table parsing is the same. Again the HIWORD_MASK flag must be added
> as a property.

OK

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

* [PATCH v5 1/4] clk: hi3xxx: add clock support
  2013-06-17 21:50   ` Olof Johansson
  2013-06-25  3:50     ` Haojian Zhuang
@ 2013-07-01 19:06     ` Mark Brown
  1 sibling, 0 replies; 15+ messages in thread
From: Mark Brown @ 2013-07-01 19:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 17, 2013 at 02:50:39PM -0700, Olof Johansson wrote:

> > +   hisilicon,clkdiv-table property.
> > + - hisilicon,clkdiv-table : list of value that are used to configure clock

> For a binding that is your own, you don't need to prefix the properties.
> Prefixes are mostly used when adding new vendor-specific attributes to a common
> binding.

People seem to be *very* keen on adding them for all bindings for some
reason.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130701/d8c039f1/attachment.sig>

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

end of thread, other threads:[~2013-07-01 19:06 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-17  8:56 [PATCH v5 0/4] support Hisilicon SoC Haojian Zhuang
2013-06-17  8:56 ` [PATCH v5 1/4] clk: hi3xxx: add clock support Haojian Zhuang
2013-06-17 21:50   ` Olof Johansson
2013-06-25  3:50     ` Haojian Zhuang
2013-07-01 19:06     ` Mark Brown
2013-06-20 20:22   ` Mike Turquette
2013-06-25  3:59     ` Haojian Zhuang
2013-06-17  8:56 ` [PATCH v5 2/4] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
2013-06-17 21:51   ` Olof Johansson
2013-06-17  8:56 ` [PATCH v5 3/4] ARM: hi3xxx: add board support with device tree Haojian Zhuang
2013-06-17 21:51   ` Olof Johansson
2013-06-17  8:56 ` [PATCH v5 4/4] ARM: hi3xxx: enable hi4511 " Haojian Zhuang
2013-06-17 17:41   ` Jean-Christophe PLAGNIOL-VILLARD
2013-06-17 21:39     ` Olof Johansson
2013-06-17 22:05   ` Olof Johansson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.