All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 0/7] enable hi3xxx SoC
@ 2013-10-15  9:16 ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A

v10:
 1. Use static IO mapping in Hi3xxx.
 2. Totally drop to support of Hi3716.
 3. Rename smp-off property to smp-offset.
 4. Remove hardcoding in hotplug driver.

v9:
 1. Clean code in DTS file according to Olof's comments.
 2. Since debug ll patch is going through Russell's tree, remove it
 from this patch set.

 v8:
 1. Drop to support CLK_GATE_SEPERATED_REG in common clock gate driver.
 Support this feature in hi3xxx clock driver.
 2. Clean unnecessary device node in DTS.
 3. Define all clocks in hi3620-clk.dtsi. And all clock nodes are defined
 in the clocks node.
 4. Fix the clock gate & clock mux for timer.
 5. Rename timer0~4 to dual_timer0~4 in DTS file. It's used to make
 name clearer.

 v7:
 1. Add hi3xxx_defconfig.
 2. Use reg property in clock node.
 3. Drop origin clock divider table.
 4. Reuse clock divider register helper.
 5. Reuse clock gate register helper.
 6. Append CLK_GATE_SEPERATED_REG flag in order to support Hisilicon
    Hi3620 SoC.
 7. Rebase DEBUG_LL for Hi3xxx.
 8. Add more clock node in DTS file.

 v6:
 1. Remove hisilicon string from properties in clock driver.
 2. Replace array by pointer in clock driver. Since only sctrl parent
    node exists at this time.

 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.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 0/7] enable hi3xxx SoC
@ 2013-10-15  9:16 ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

v10:
 1. Use static IO mapping in Hi3xxx.
 2. Totally drop to support of Hi3716.
 3. Rename smp-off property to smp-offset.
 4. Remove hardcoding in hotplug driver.

v9:
 1. Clean code in DTS file according to Olof's comments.
 2. Since debug ll patch is going through Russell's tree, remove it
 from this patch set.

 v8:
 1. Drop to support CLK_GATE_SEPERATED_REG in common clock gate driver.
 Support this feature in hi3xxx clock driver.
 2. Clean unnecessary device node in DTS.
 3. Define all clocks in hi3620-clk.dtsi. And all clock nodes are defined
 in the clocks node.
 4. Fix the clock gate & clock mux for timer.
 5. Rename timer0~4 to dual_timer0~4 in DTS file. It's used to make
 name clearer.

 v7:
 1. Add hi3xxx_defconfig.
 2. Use reg property in clock node.
 3. Drop origin clock divider table.
 4. Reuse clock divider register helper.
 5. Reuse clock gate register helper.
 6. Append CLK_GATE_SEPERATED_REG flag in order to support Hisilicon
    Hi3620 SoC.
 7. Rebase DEBUG_LL for Hi3xxx.
 8. Add more clock node in DTS file.

 v6:
 1. Remove hisilicon string from properties in clock driver.
 2. Replace array by pointer in clock driver. Since only sctrl parent
    node exists at this time.

 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] 38+ messages in thread

* [PATCH v10 1/7] clk: hi3xxx: add clock support
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Add clock support with device tree on Hisilicon SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Mike Turquette <mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/clock/hisilicon.txt        |  99 +++++++++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/hisilicon/Makefile                     |   2 +
 drivers/clk/hisilicon/clk-hi3xxx.c                 | 221 +++++++++++++++++++++
 drivers/clk/hisilicon/clk-hi3xxx.h                 |  34 ++++
 drivers/clk/hisilicon/clkgate-seperated.c          | 129 ++++++++++++
 6 files changed, 486 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
 create mode 100644 drivers/clk/hisilicon/Makefile
 create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.c
 create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.h
 create mode 100644 drivers/clk/hisilicon/clkgate-seperated.c

diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
new file mode 100644
index 0000000..c29b9ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
@@ -0,0 +1,99 @@
+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,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.
+ - reg : the mux register address. It should be the offset of the container.
+ - clkmux-mask : mask bits of the mux register.
+ - clkmux-table : array of mux select bits.
+
+Optional properties for mux clocks:
+ - clkmux-hiword-mask : indicates that the bit[31:16] are the hiword mask
+	of mux selected bits (bit[15:0]). The bit[15:0] is valid only when
+	bit[31:16] is set.
+
+
+
+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.
+ - reg : the mux register address. It should be the offset of the container.
+ - clkgate : bit index to control the clock gate in the gate register.
+
+Optional properties for gate clocks:
+ - clkgate-inverted : it indicates that setting 0 could enable the clock gate
+	and setting 1 could disable the clock gate.
+ - clkgate-seperated-reg : it indicates that there're three continuous
+	registers (enable, disable & status) for the same clock gate.
+
+
+
+Required properties for divider clocks:
+ - compatible : shall be "hisilicon,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.
+ - reg : the divider register address. It should be the offset of the
+	container.
+ - clkdiv-mask : mask bits of the divider register.
+ - clkdiv-min : the minimum divider of the clock divider.
+ - clkdiv-max : the maximum divider of the clock divider.
+
+Optional properties for divider clocks:
+ - clkdiv-hiword-mask : indicates that the bit[31:16] are the hiword mask
+	of divider selected bits (bit[15:0]). The bit[15:0] is valid only when
+	bit[31:16] is set.
+
+
+
+For example:
+		timer0_mux: timer0_mux@fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer0_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x8000>;
+			clkmux-table = <0 0x8000>;
+		};
+		uart0_mux: uart0_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x80>;
+			/* each item value */
+			clkmux-table = <0 0x80>;
+			clkmux-hiword-mask;
+		};
+		timerclk01: timerclk01@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk01>;
+			clock-output-names = "timerclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <0>;
+			clkgate-seperated-reg;
+		};
+		mmc1_div: mmc1_div@fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc1_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7b11106..b88d9e4 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)	+= hisilicon/
 obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
 obj-$(CONFIG_ARCH_NSPIRE)	+= clk-nspire.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs/
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
new file mode 100644
index 0000000..1ed6a3c
--- /dev/null
+++ b/drivers/clk/hisilicon/Makefile
@@ -0,0 +1,2 @@
+
+obj-y	+= clk-hi3xxx.o clkgate-seperated.o
diff --git a/drivers/clk/hisilicon/clk-hi3xxx.c b/drivers/clk/hisilicon/clk-hi3xxx.c
new file mode 100644
index 0000000..daa9cfa
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3xxx.c
@@ -0,0 +1,221 @@
+/*
+ * Hisilicon Hi3xxx clock driver
+ *
+ * Copyright (c) 2012-2013 Hisilicon Limited.
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *	   Xin Li <li.xin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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/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>
+
+#include "clk-hi3xxx.h"
+
+static DEFINE_SPINLOCK(hi3xxx_clk_lock);
+
+static void __init hi3xxx_clkgate_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names, *name;
+	unsigned long flags = 0;
+	u32 bit_idx;
+	void __iomem *reg;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkgate", &bit_idx))
+		goto err;
+
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		goto err;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	if (of_property_read_bool(np, "clkgate-seperated-reg")) {
+		clk = hi3xxx_register_clkgate_sep(NULL, clk_name, parent_names[0],
+						  0, reg, (u8)bit_idx, flags,
+						  &hi3xxx_clk_lock);
+	} else {
+		if (of_property_read_bool(np, "clkgate-inverted"))
+			flags |= CLK_GATE_SET_TO_DISABLE;
+		clk = clk_register_gate(NULL, clk_name, parent_names[0], 0, reg,
+					(u8)bit_idx, flags, &hi3xxx_clk_lock);
+	}
+	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(parent_names);
+err:
+	pr_err("Fail on registering hi3xxx clkgate node.\n");
+}
+CLK_OF_DECLARE(hi3xxx_gate, "hisilicon,clk-gate", hi3xxx_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 */
+	cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+	if (cnt < 0) {
+		pr_err("%s: failed to find clock parent\n", __func__);
+		return cnt;
+	}
+
+	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, "clkmux-table",
+					 table, cnt);
+	if (ret)
+		goto err;
+	return 0;
+err:
+	kfree(table);
+	return ret;
+}
+
+static void __init hi3xxx_clkmux_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names = NULL;
+	u32 mask, *table = NULL;
+	u8 num_parents, shift, clk_mux_flags = 0;
+	void __iomem *reg;
+	int i, ret;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkmux-mask", &mask))
+		goto err;
+	if (of_property_read_bool(np, "clkmux-hiword-mask"))
+		clk_mux_flags = CLK_MUX_HIWORD_MASK;
+
+	ret = hi3xxx_parse_mux(np, &num_parents, table);
+	if (ret)
+		goto err;
+
+	parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+	if (!parent_names)
+		goto err_table;
+	for (i = 0; i < num_parents; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+
+	shift = ffs(mask) - 1;
+	mask = mask >> shift;
+	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_table:
+	kfree(table);
+err:
+	pr_err("Fail on registering hi3xxx clkmux node.\n");
+}
+CLK_OF_DECLARE(hi3xxx_mux, "hisilicon,clk-mux", hi3xxx_clkmux_setup)
+
+static void __init hi3xxx_clkdiv_setup(struct device_node *np, int mode)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	struct clk_div_table *table;
+	unsigned int table_num;
+	u32 min, max, mask;
+	u8 shift, width, clk_div_flags = 0;
+	void __iomem *reg;
+	int i;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-mask", &mask))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-min", &min))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-max", &max))
+		goto err;
+	if (of_property_read_bool(np, "clkdiv-hiword-mask"))
+		clk_div_flags = CLK_DIVIDER_HIWORD_MASK;
+
+	table_num = max - min + 1;
+	table = kzalloc(sizeof(*table) * table_num, GFP_KERNEL);
+	if (!table)
+		goto err;
+
+	for (i = 0; i < table_num; i++) {
+		table[i].div = min + i;
+		table[i].val = table[i].div - 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);
+	shift = ffs(mask) - 1;
+	width = fls(mask) - ffs(mask) + 1;
+	clk = clk_register_divider_table(NULL, clk_name, parent_names[0], 0,
+					 reg, shift, width, clk_div_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_par:
+	kfree(table);
+err:
+	pr_err("Fail on registering hi3xxx clkdiv node\n");
+}
+CLK_OF_DECLARE(hi3xxx_div, "hisilicon,clk-div", hi3xxx_clkdiv_setup)
diff --git a/drivers/clk/hisilicon/clk-hi3xxx.h b/drivers/clk/hisilicon/clk-hi3xxx.h
new file mode 100644
index 0000000..52c4d22
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3xxx.h
@@ -0,0 +1,34 @@
+/*
+ * Hisilicon Hi3620 clock gate driver
+ *
+ * Copyright (c) 2012-2013 Hisilicon Limited.
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *	   Xin Li <li.xin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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.
+ *
+ */
+
+#ifndef	__HI3XXX_CLKGATE_SEPERATED
+#define	__HI3XXX_CLKGATE_SEPERATED
+
+extern struct clk *hi3xxx_register_clkgate_sep(struct device *, const char *,
+				const char *, unsigned long,
+				void __iomem *, u8,
+				u8, spinlock_t *);
+
+#endif	/* __HI3XXX_CLKGATE_SEPERATED */
diff --git a/drivers/clk/hisilicon/clkgate-seperated.c b/drivers/clk/hisilicon/clkgate-seperated.c
new file mode 100644
index 0000000..1d7b0da
--- /dev/null
+++ b/drivers/clk/hisilicon/clkgate-seperated.c
@@ -0,0 +1,129 @@
+/*
+ * Hisilicon Hi3620 clock gate driver
+ *
+ * Copyright (c) 2012-2013 Hisilicon Limited.
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *	   Xin Li <li.xin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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/clkdev.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#include "clk-hi3xxx.h"
+
+/* Hi3620 clock gate register offset */
+#define CLKGATE_SEPERATED_ENABLE		0x0
+#define CLKGATE_SEPERATED_DISABLE		0x4
+#define CLKGATE_SEPERATED_STATUS		0x8
+
+struct clkgate_seperated {
+	struct clk_hw	hw;
+	void __iomem	*enable;	/* enable register */
+	u8		bit_idx;	/* bits in enable/disable register */
+	u8		flags;
+	spinlock_t	*lock;
+};
+
+static int clkgate_seperated_enable(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	unsigned long flags = 0;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	if (sclk->lock)
+		spin_lock_irqsave(sclk->lock, flags);
+	reg = BIT(sclk->bit_idx);
+	writel_relaxed(reg, sclk->enable);
+	readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	if (sclk->lock)
+		spin_unlock_irqrestore(sclk->lock, flags);
+	return 0;
+}
+
+static void clkgate_seperated_disable(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	unsigned long flags = 0;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	if (sclk->lock)
+		spin_lock_irqsave(sclk->lock, flags);
+	reg = BIT(sclk->bit_idx);
+	writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE);
+	readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	if (sclk->lock)
+		spin_unlock_irqrestore(sclk->lock, flags);
+}
+
+static int clkgate_seperated_is_enabled(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	reg &= BIT(sclk->bit_idx);
+
+	return reg ? 1 : 0;
+}
+
+static struct clk_ops clkgate_seperated_ops = {
+	.enable		= clkgate_seperated_enable,
+	.disable	= clkgate_seperated_disable,
+	.is_enabled	= clkgate_seperated_is_enabled,
+};
+
+struct clk *hi3xxx_register_clkgate_sep(struct device *dev, const char *name,
+				const char *parent_name, unsigned long flags,
+				void __iomem *reg, u8 bit_idx,
+				u8 clk_gate_flags, spinlock_t *lock)
+{
+	struct clkgate_seperated *sclk;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	sclk = kzalloc(sizeof(struct clkgate_seperated), GFP_KERNEL);
+	if (!sclk) {
+		pr_err("%s: fail to allocate seperated gated clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &clkgate_seperated_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	sclk->enable = reg + CLKGATE_SEPERATED_ENABLE;
+	sclk->bit_idx = bit_idx;
+	sclk->flags = clk_gate_flags;
+	sclk->hw.init = &init;
+
+	clk = clk_register(dev, &sclk->hw);
+	if (IS_ERR(clk))
+		kfree(sclk);
+	return clk;
+}
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 1/7] clk: hi3xxx: add clock support
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 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        |  99 +++++++++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/hisilicon/Makefile                     |   2 +
 drivers/clk/hisilicon/clk-hi3xxx.c                 | 221 +++++++++++++++++++++
 drivers/clk/hisilicon/clk-hi3xxx.h                 |  34 ++++
 drivers/clk/hisilicon/clkgate-seperated.c          | 129 ++++++++++++
 6 files changed, 486 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
 create mode 100644 drivers/clk/hisilicon/Makefile
 create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.c
 create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.h
 create mode 100644 drivers/clk/hisilicon/clkgate-seperated.c

diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
new file mode 100644
index 0000000..c29b9ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
@@ -0,0 +1,99 @@
+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,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.
+ - reg : the mux register address. It should be the offset of the container.
+ - clkmux-mask : mask bits of the mux register.
+ - clkmux-table : array of mux select bits.
+
+Optional properties for mux clocks:
+ - clkmux-hiword-mask : indicates that the bit[31:16] are the hiword mask
+	of mux selected bits (bit[15:0]). The bit[15:0] is valid only when
+	bit[31:16] is set.
+
+
+
+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.
+ - reg : the mux register address. It should be the offset of the container.
+ - clkgate : bit index to control the clock gate in the gate register.
+
+Optional properties for gate clocks:
+ - clkgate-inverted : it indicates that setting 0 could enable the clock gate
+	and setting 1 could disable the clock gate.
+ - clkgate-seperated-reg : it indicates that there're three continuous
+	registers (enable, disable & status) for the same clock gate.
+
+
+
+Required properties for divider clocks:
+ - compatible : shall be "hisilicon,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.
+ - reg : the divider register address. It should be the offset of the
+	container.
+ - clkdiv-mask : mask bits of the divider register.
+ - clkdiv-min : the minimum divider of the clock divider.
+ - clkdiv-max : the maximum divider of the clock divider.
+
+Optional properties for divider clocks:
+ - clkdiv-hiword-mask : indicates that the bit[31:16] are the hiword mask
+	of divider selected bits (bit[15:0]). The bit[15:0] is valid only when
+	bit[31:16] is set.
+
+
+
+For example:
+		timer0_mux: timer0_mux at fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer0_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x8000>;
+			clkmux-table = <0 0x8000>;
+		};
+		uart0_mux: uart0_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x80>;
+			/* each item value */
+			clkmux-table = <0 0x80>;
+			clkmux-hiword-mask;
+		};
+		timerclk01: timerclk01 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk01>;
+			clock-output-names = "timerclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <0>;
+			clkgate-seperated-reg;
+		};
+		mmc1_div: mmc1_div at fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc1_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7b11106..b88d9e4 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)	+= hisilicon/
 obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
 obj-$(CONFIG_ARCH_NSPIRE)	+= clk-nspire.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs/
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
new file mode 100644
index 0000000..1ed6a3c
--- /dev/null
+++ b/drivers/clk/hisilicon/Makefile
@@ -0,0 +1,2 @@
+
+obj-y	+= clk-hi3xxx.o clkgate-seperated.o
diff --git a/drivers/clk/hisilicon/clk-hi3xxx.c b/drivers/clk/hisilicon/clk-hi3xxx.c
new file mode 100644
index 0000000..daa9cfa
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3xxx.c
@@ -0,0 +1,221 @@
+/*
+ * Hisilicon Hi3xxx 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/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>
+
+#include "clk-hi3xxx.h"
+
+static DEFINE_SPINLOCK(hi3xxx_clk_lock);
+
+static void __init hi3xxx_clkgate_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names, *name;
+	unsigned long flags = 0;
+	u32 bit_idx;
+	void __iomem *reg;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkgate", &bit_idx))
+		goto err;
+
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		goto err;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	if (of_property_read_bool(np, "clkgate-seperated-reg")) {
+		clk = hi3xxx_register_clkgate_sep(NULL, clk_name, parent_names[0],
+						  0, reg, (u8)bit_idx, flags,
+						  &hi3xxx_clk_lock);
+	} else {
+		if (of_property_read_bool(np, "clkgate-inverted"))
+			flags |= CLK_GATE_SET_TO_DISABLE;
+		clk = clk_register_gate(NULL, clk_name, parent_names[0], 0, reg,
+					(u8)bit_idx, flags, &hi3xxx_clk_lock);
+	}
+	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(parent_names);
+err:
+	pr_err("Fail on registering hi3xxx clkgate node.\n");
+}
+CLK_OF_DECLARE(hi3xxx_gate, "hisilicon,clk-gate", hi3xxx_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 */
+	cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+	if (cnt < 0) {
+		pr_err("%s: failed to find clock parent\n", __func__);
+		return cnt;
+	}
+
+	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, "clkmux-table",
+					 table, cnt);
+	if (ret)
+		goto err;
+	return 0;
+err:
+	kfree(table);
+	return ret;
+}
+
+static void __init hi3xxx_clkmux_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names = NULL;
+	u32 mask, *table = NULL;
+	u8 num_parents, shift, clk_mux_flags = 0;
+	void __iomem *reg;
+	int i, ret;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkmux-mask", &mask))
+		goto err;
+	if (of_property_read_bool(np, "clkmux-hiword-mask"))
+		clk_mux_flags = CLK_MUX_HIWORD_MASK;
+
+	ret = hi3xxx_parse_mux(np, &num_parents, table);
+	if (ret)
+		goto err;
+
+	parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);
+	if (!parent_names)
+		goto err_table;
+	for (i = 0; i < num_parents; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+
+	shift = ffs(mask) - 1;
+	mask = mask >> shift;
+	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_table:
+	kfree(table);
+err:
+	pr_err("Fail on registering hi3xxx clkmux node.\n");
+}
+CLK_OF_DECLARE(hi3xxx_mux, "hisilicon,clk-mux", hi3xxx_clkmux_setup)
+
+static void __init hi3xxx_clkdiv_setup(struct device_node *np, int mode)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	struct clk_div_table *table;
+	unsigned int table_num;
+	u32 min, max, mask;
+	u8 shift, width, clk_div_flags = 0;
+	void __iomem *reg;
+	int i;
+
+	reg = of_iomap(np, 0);
+	if (!reg)
+		goto err;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-mask", &mask))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-min", &min))
+		goto err;
+	if (of_property_read_u32(np, "clkdiv-max", &max))
+		goto err;
+	if (of_property_read_bool(np, "clkdiv-hiword-mask"))
+		clk_div_flags = CLK_DIVIDER_HIWORD_MASK;
+
+	table_num = max - min + 1;
+	table = kzalloc(sizeof(*table) * table_num, GFP_KERNEL);
+	if (!table)
+		goto err;
+
+	for (i = 0; i < table_num; i++) {
+		table[i].div = min + i;
+		table[i].val = table[i].div - 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);
+	shift = ffs(mask) - 1;
+	width = fls(mask) - ffs(mask) + 1;
+	clk = clk_register_divider_table(NULL, clk_name, parent_names[0], 0,
+					 reg, shift, width, clk_div_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_par:
+	kfree(table);
+err:
+	pr_err("Fail on registering hi3xxx clkdiv node\n");
+}
+CLK_OF_DECLARE(hi3xxx_div, "hisilicon,clk-div", hi3xxx_clkdiv_setup)
diff --git a/drivers/clk/hisilicon/clk-hi3xxx.h b/drivers/clk/hisilicon/clk-hi3xxx.h
new file mode 100644
index 0000000..52c4d22
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3xxx.h
@@ -0,0 +1,34 @@
+/*
+ * Hisilicon Hi3620 clock gate 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.
+ *
+ */
+
+#ifndef	__HI3XXX_CLKGATE_SEPERATED
+#define	__HI3XXX_CLKGATE_SEPERATED
+
+extern struct clk *hi3xxx_register_clkgate_sep(struct device *, const char *,
+				const char *, unsigned long,
+				void __iomem *, u8,
+				u8, spinlock_t *);
+
+#endif	/* __HI3XXX_CLKGATE_SEPERATED */
diff --git a/drivers/clk/hisilicon/clkgate-seperated.c b/drivers/clk/hisilicon/clkgate-seperated.c
new file mode 100644
index 0000000..1d7b0da
--- /dev/null
+++ b/drivers/clk/hisilicon/clkgate-seperated.c
@@ -0,0 +1,129 @@
+/*
+ * Hisilicon Hi3620 clock gate 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/clkdev.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#include "clk-hi3xxx.h"
+
+/* Hi3620 clock gate register offset */
+#define CLKGATE_SEPERATED_ENABLE		0x0
+#define CLKGATE_SEPERATED_DISABLE		0x4
+#define CLKGATE_SEPERATED_STATUS		0x8
+
+struct clkgate_seperated {
+	struct clk_hw	hw;
+	void __iomem	*enable;	/* enable register */
+	u8		bit_idx;	/* bits in enable/disable register */
+	u8		flags;
+	spinlock_t	*lock;
+};
+
+static int clkgate_seperated_enable(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	unsigned long flags = 0;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	if (sclk->lock)
+		spin_lock_irqsave(sclk->lock, flags);
+	reg = BIT(sclk->bit_idx);
+	writel_relaxed(reg, sclk->enable);
+	readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	if (sclk->lock)
+		spin_unlock_irqrestore(sclk->lock, flags);
+	return 0;
+}
+
+static void clkgate_seperated_disable(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	unsigned long flags = 0;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	if (sclk->lock)
+		spin_lock_irqsave(sclk->lock, flags);
+	reg = BIT(sclk->bit_idx);
+	writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE);
+	readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	if (sclk->lock)
+		spin_unlock_irqrestore(sclk->lock, flags);
+}
+
+static int clkgate_seperated_is_enabled(struct clk_hw *hw)
+{
+	struct clkgate_seperated *sclk;
+	u32 reg;
+
+	sclk = container_of(hw, struct clkgate_seperated, hw);
+	reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
+	reg &= BIT(sclk->bit_idx);
+
+	return reg ? 1 : 0;
+}
+
+static struct clk_ops clkgate_seperated_ops = {
+	.enable		= clkgate_seperated_enable,
+	.disable	= clkgate_seperated_disable,
+	.is_enabled	= clkgate_seperated_is_enabled,
+};
+
+struct clk *hi3xxx_register_clkgate_sep(struct device *dev, const char *name,
+				const char *parent_name, unsigned long flags,
+				void __iomem *reg, u8 bit_idx,
+				u8 clk_gate_flags, spinlock_t *lock)
+{
+	struct clkgate_seperated *sclk;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	sclk = kzalloc(sizeof(struct clkgate_seperated), GFP_KERNEL);
+	if (!sclk) {
+		pr_err("%s: fail to allocate seperated gated clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &clkgate_seperated_ops;
+	init.flags = flags | CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	sclk->enable = reg + CLKGATE_SEPERATED_ENABLE;
+	sclk->bit_idx = bit_idx;
+	sclk->flags = clk_gate_flags;
+	sclk->hw.init = &init;
+
+	clk = clk_register(dev, &sclk->hw);
+	if (IS_ERR(clk))
+		kfree(sclk);
+	return clk;
+}
-- 
1.8.1.2

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Add board support with device tree for Hisilicon Hi3620 SoC platform.

Changelog:
v10:
1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
only called if .map_io() isn't assigned. Use .map_io() to setup static
IO mapping that is used in clock driver.

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-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../bindings/arm/hisilicon/hisilicon.txt           | 10 +++++
 arch/arm/Kconfig                                   |  2 +
 arch/arm/Makefile                                  |  1 +
 arch/arm/mach-hi3xxx/Kconfig                       | 12 +++++
 arch/arm/mach-hi3xxx/Makefile                      |  5 +++
 arch/arm/mach-hi3xxx/hi3xxx.c                      | 52 ++++++++++++++++++++++
 6 files changed, 82 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 3f7714d..0118443 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -946,6 +946,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 a37a50f..23fb0b0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -155,6 +155,7 @@ machine-$(CONFIG_ARCH_EBSA110)		+= ebsa110
 machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
 machine-$(CONFIG_ARCH_EXYNOS)		+= exynos
 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..68bd26c
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/Kconfig
@@ -0,0 +1,12 @@
+config ARCH_HI3xxx
+	bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select ARM_TIMER_SP804
+	select CACHE_L2X0
+	select CLKSRC_OF
+	select GENERIC_CLOCKEVENTS
+	select PINCTRL
+	select PINCTRL_SINGLE
+	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..4220860
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/hi3xxx.c
@@ -0,0 +1,52 @@
+/*
+ * (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-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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 struct map_desc hi3620_io_desc[] __initdata = {
+	{
+		.pfn		= __phys_to_pfn(0xfc802000),
+		.virtual	= 0xfe802000,
+		.length		= 0x1000,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init hi3620_map_io(void)
+{
+	debug_ll_io_init();
+	iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc));
+}
+
+static void __init hi3xxx_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static const char *hi3xxx_compat[] __initdata = {
+	"hisilicon,hi3620-hi4511",
+	NULL,
+};
+
+DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
+	.map_io		= hi3620_map_io,
+	.init_time	= hi3xxx_timer_init,
+	.dt_compat	= hi3xxx_compat,
+MACHINE_END
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add board support with device tree for Hisilicon Hi3620 SoC platform.

Changelog:
v10:
1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
only called if .map_io() isn't assigned. Use .map_io() to setup static
IO mapping that is used in clock driver.

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                       | 12 +++++
 arch/arm/mach-hi3xxx/Makefile                      |  5 +++
 arch/arm/mach-hi3xxx/hi3xxx.c                      | 52 ++++++++++++++++++++++
 6 files changed, 82 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 3f7714d..0118443 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -946,6 +946,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 a37a50f..23fb0b0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -155,6 +155,7 @@ machine-$(CONFIG_ARCH_EBSA110)		+= ebsa110
 machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
 machine-$(CONFIG_ARCH_EXYNOS)		+= exynos
 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..68bd26c
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/Kconfig
@@ -0,0 +1,12 @@
+config ARCH_HI3xxx
+	bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select ARM_TIMER_SP804
+	select CACHE_L2X0
+	select CLKSRC_OF
+	select GENERIC_CLOCKEVENTS
+	select PINCTRL
+	select PINCTRL_SINGLE
+	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..4220860
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/hi3xxx.c
@@ -0,0 +1,52 @@
+/*
+ * (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 struct map_desc hi3620_io_desc[] __initdata = {
+	{
+		.pfn		= __phys_to_pfn(0xfc802000),
+		.virtual	= 0xfe802000,
+		.length		= 0x1000,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init hi3620_map_io(void)
+{
+	debug_ll_io_init();
+	iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc));
+}
+
+static void __init hi3xxx_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static const char *hi3xxx_compat[] __initdata = {
+	"hisilicon,hi3620-hi4511",
+	NULL,
+};
+
+DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
+	.map_io		= hi3620_map_io,
+	.init_time	= hi3xxx_timer_init,
+	.dt_compat	= hi3xxx_compat,
+MACHINE_END
-- 
1.8.1.2

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Enable Hisilicon Hi4511 development platform with device tree support.

Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/boot/dts/Makefile        |    1 +
 arch/arm/boot/dts/hi3620-clk.dtsi | 1052 +++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/hi3620.dtsi     |  513 ++++++++++++++++++
 arch/arm/boot/dts/hi4511.dts      |  648 +++++++++++++++++++++++
 4 files changed, 2214 insertions(+)
 create mode 100644 arch/arm/boot/dts/hi3620-clk.dtsi
 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 cc0f1fb..b4ec185 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
 	exynos5420-smdk5420.dtb \
 	exynos5440-sd5v1.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-clk.dtsi b/arch/arm/boot/dts/hi3620-clk.dtsi
new file mode 100644
index 0000000..51233d3
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620-clk.dtsi
@@ -0,0 +1,1052 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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.
+ */
+
+/ {
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		osc32k: osc32k {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "osc32khz";
+		};
+		osc26m: osc26m {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+			clock-output-names = "osc26mhz";
+		};
+		pclk: pclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+			clock-output-names = "apb_pclk";
+		};
+		pll_arm0: pll_arm0 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1600000000>;
+			clock-output-names = "armpll0";
+		};
+		pll_arm1: pll_arm1 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1600000000>;
+			clock-output-names = "armpll1";
+		};
+		pll_peri: pll_peri {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1440000000>;
+			clock-output-names = "armpll2";
+		};
+		pll_usb: pll_usb {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1440000000>;
+			clock-output-names = "armpll3";
+		};
+		pll_hdmi: pll_hdmi {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1188000000>;
+			clock-output-names = "armpll4";
+		};
+		pll_gpu: pll_gpu {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1300000000>;
+			clock-output-names = "armpll5";
+		};
+		rclk_tcxo: rclk_tcxo {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "rclk_tcxo";
+			clock-mult = <1>;
+			clock-div = <4>;
+		};
+		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>;
+		};
+		rclk_pico: rclk_pico {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+			clocks = <&hsic_div>;
+			clock-output-names = "rclk_pico";
+			clock-mult = <1>;
+			clock-div = <40>;
+		};
+
+		timer0_mux: timer0_mux@fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer0_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x18000>;
+			clkmux-table = <0 0x8000>;
+		};
+		timer1_mux: timer1_mux@fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer1_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x60000>;
+			clkmux-table = <0 0x20000>;
+		};
+		timer2_mux: timer2_mux@fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk23>;
+			clock-output-names = "timer2_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x180000>;
+			clkmux-table = <0 0x80000>;
+		};
+		timer3_mux: timer3_mux@fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk23>;
+			clock-output-names = "timer3_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x600000>;
+			clkmux-table = <0 0x200000>;
+		};
+		timer4_mux: timer4_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk45>;
+			clock-output-names = "timer4_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x3>;
+			clkmux-table = <0 0x1>;
+		};
+		timer5_mux: timer5_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk45>;
+			clock-output-names = "timer5_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc>;
+			clkmux-table = <0 0x4>;
+		};
+		timer6_mux: timer6_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk67>;
+			clock-output-names = "timer6_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x30>;
+			clkmux-table = <0 0x10>;
+		};
+		timer7_mux: timer7_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk67>;
+			clock-output-names = "timer7_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc0>;
+			clkmux-table = <0 0x40>;
+		};
+		timer8_mux: timer8_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk89>;
+			clock-output-names = "timer8_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x300>;
+			clkmux-table = <0 0x100>;
+		};
+		timer9_mux: timer9_mux@fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk89>;
+			clock-output-names = "timer9_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc00>;
+			clkmux-table = <0 0x400>;
+		};
+
+		uart0_mux: uart0_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x80>;
+			/* each item value */
+			clkmux-table = <0 0x80>;
+			clkmux-hiword-mask;
+		};
+		uart1_mux: uart1_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart1_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x100>;
+			clkmux-table = <0x0 0x100>;
+			clkmux-hiword-mask;
+		};
+		uart2_mux: uart2_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart2_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+		uart3_mux: uart3_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart3_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		uart4_mux: uart4_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart4_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		spi0_mux: spi0_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x1000>;
+			clkmux-table = <0 0x1000>;
+			clkmux-hiword-mask;
+		};
+		spi1_mux: spi1_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi1_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x2000>;
+			clkmux-table = <0 0x2000>;
+			clkmux-hiword-mask;
+		};
+		spi2_mux: spi2_mux@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi2_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x4000>;
+			clkmux-table = <0 0x4000>;
+			clkmux-hiword-mask;
+		};
+		rclk_shareAXI: rclk_shareAXI@fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "rclk_shareAXI";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x8000>;
+			clkmux-table = <0 0x8000>;
+			clkmux-hiword-mask;
+		};
+		pwm0_mux: pwm0_mux@fc802104 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &osc26m>;
+			clock-output-names = "pwm0_mux";
+			reg = <0xfc802104 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		pwm1_mux: pwm1_mux@fc802104 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &osc26m>;
+			clock-output-names = "pwm1_mux";
+			reg = <0xfc802104 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		sd_mux: sd_mux@fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "sd_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x10>;
+			clkmux-table = <0 0x10>;
+			clkmux-hiword-mask;
+		};
+		mmc1_mux: mmc1_mux@fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc1_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+		rclk_mmc1_mux: rclk_mmc1_mux@fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &mmc1_div>;
+			clock-output-names = "rclk_mmc1_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		g2d_mux: g2d_mux@fc80210c {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "g2d_mux";
+			reg = <0xfc80210c 0x4>;
+			clkmux-mask = <0x20>;
+			clkmux-table = <0 0x20>;
+			clkmux-hiword-mask;
+		};
+		venc_mux: venc_mux@fc80210c {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "venc_mux";
+			reg = <0xfc80210c 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		vdec_mux: vdec_mux@fc802110 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "vdec_mux";
+			reg = <0xfc802110 0x4>;
+			clkmux-mask = <0x20>;
+			clkmux-table = <0 0x20>;
+			clkmux-hiword-mask;
+		};
+		vpp_mux: vpp_mux@fc802110 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "vpp_mux";
+			reg = <0xfc802110 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		edc0_mux: edc0_mux@fc802114 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "edc0_mux";
+			reg = <0xfc802114 0x4>;
+			clkmux-mask = <0x40>;
+			clkmux-table = <0 0x40>;
+			clkmux-hiword-mask;
+		};
+		ldi0_mux: ldi0_mux@fc802114 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_hdmi &pll_usb &pll_gpu>;
+			clock-output-names = "ldi0_mux";
+			reg = <0xfc802114 0x4>;
+			clkmux-mask = <0x6000>;
+			clkmux-table = <0 0x2000 0x4000 0x6000>;
+			clkmux-hiword-mask;
+		};
+		edc1_mux: edc1_mux@fc802118 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "edc1_mux";
+			reg = <0xfc802118 0x4>;
+			clkmux-mask = <0x40>;
+			clkmux-table = <0 0x40>;
+			clkmux-hiword-mask;
+		};
+		ldi1_mux: ldi1_mux@fc802118 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_hdmi &pll_usb &pll_gpu>;
+			clock-output-names = "ldi1_mux";
+			reg = <0xfc802118 0x4>;
+			clkmux-mask = <0xc000>;
+			clkmux-table = <0 0x4000 0x8000 0xc000>;
+			clkmux-hiword-mask;
+		};
+		rclk_hsic: rclk_hsic@fc802130 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "rclk_hsic";
+			reg = <0xfc802130 0x4>;
+			clkmux-mask = <0x4>;
+			clkmux-table = <0 0x4>;
+			clkmux-hiword-mask;
+		};
+		mmc2_mux: mmc2_mux@fc802140 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc2_mux";
+			reg = <0xfc802140 0x4>;
+			clkmux-mask = <0x10>;
+			clkmux-table = <0 0x10>;
+			clkmux-hiword-mask;
+		};
+		mmc3_mux: mmc3_mux@fc802140 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc3_mux";
+			reg = <0xfc802140 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+
+		shareaxi_div: shareaxi_div@fc802100 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&rclk_shareAXI>;
+			clock-output-names = "shareaxi_div";
+			reg = <0xfc802100 0x4>;
+			clkdiv-mask = <0x1f>;
+			clkdiv-min = <1>;
+			clkdiv-max = <32>;
+			clkdiv-hiword-mask;
+		};
+		cfgaxi_div: cfgaxi_div@fc802100 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&shareaxi_div>;
+			clock-output-names = "cfgaxi_div";
+			reg = <0xfc802100 0x4>;
+			clkdiv-mask = <0x60>;
+			clkdiv-min = <2>;
+			clkdiv-max = <2>;
+			clkdiv-hiword-mask;
+		};
+		sd_div: sd_div@fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&sd_mux>;
+			clock-output-names = "sd_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0xf>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		mmc1_div: mmc1_div@fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc1_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		hsic_div: hsic_div@fc802130 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&rclk_hsic>;
+			clock-output-names = "hsic_div";
+			reg = <0xfc802130 0x4>;
+			clkdiv-mask = <0x3>;
+			clkdiv-min = <1>;
+			clkdiv-max = <4>;
+			clkdiv-hiword-mask;
+		};
+		mmc2_div: mmc2_div@fc802140 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc2_div";
+			reg = <0xfc802140 0x4>;
+			clkdiv-mask = <0xf>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		mmc3_div: mmc3_div@fc802140 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc3_div";
+			reg = <0xfc802140 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+
+		timerclk01: timerclk01@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk01>;
+			clock-output-names = "timerclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <0>;
+			clkgate-seperated-reg;
+		};
+		timer_rclk01: timer_rclk01@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timer_rclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <1>;
+			clkgate-seperated-reg;
+		};
+		timerclk23: timerclk23@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk23>;
+			clock-output-names = "timerclk23";
+			reg = <0xfc802020 0x4>;
+			clkgate = <2>;
+			clkgate-seperated-reg;
+		};
+		timer_rclk23: timer_rclk23@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timer_rclk23";
+			reg = <0xfc802020 0x4>;
+			clkgate = <3>;
+			clkgate-seperated-reg;
+		};
+		rtcclk: rtcclk@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "rtcclk";
+			reg = <0xfc802020 0x4>;
+			clkgate = <5>;
+			clkgate-seperated-reg;
+		};
+		kpc_clk: kpc_clk@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "kpc_clk";
+			reg = <0xfc802020 0x4>;
+			clkgate = <6>;
+			clkgate-seperated-reg;
+		};
+		gpioclk0: gpioclk0@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk0";
+			reg = <0xfc802020 0x4>;
+			clkgate = <8>;
+			clkgate-seperated-reg;
+		};
+		gpioclk1: gpioclk1@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk1";
+			reg = <0xfc802020 0x4>;
+			clkgate = <9>;
+			clkgate-seperated-reg;
+		};
+		gpioclk2: gpioclk2@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk2";
+			reg = <0xfc802020 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		gpioclk3: gpioclk3@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk3";
+			reg = <0xfc802020 0x4>;
+			clkgate = <11>;
+			clkgate-seperated-reg;
+		};
+		gpioclk4: gpioclk4@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk4";
+			reg = <0xfc802020 0x4>;
+			clkgate = <12>;
+			clkgate-seperated-reg;
+		};
+		gpioclk5: gpioclk5@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk5";
+			reg = <0xfc802020 0x4>;
+			clkgate = <13>;
+			clkgate-seperated-reg;
+		};
+		gpioclk6: gpioclk6@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk6";
+			reg = <0xfc802020 0x4>;
+			clkgate = <14>;
+			clkgate-seperated-reg;
+		};
+		gpioclk7: gpioclk7@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk7";
+			reg = <0xfc802020 0x4>;
+			clkgate = <15>;
+			clkgate-seperated-reg;
+		};
+		gpioclk8: gpioclk8@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk8";
+			reg = <0xfc802020 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		gpioclk9: gpioclk9@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk9";
+			reg = <0xfc802020 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		gpioclk10: gpioclk10@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk10";
+			reg = <0xfc802020 0x4>;
+			clkgate = <18>;
+			clkgate-seperated-reg;
+		};
+		gpioclk11: gpioclk11@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk11";
+			reg = <0xfc802020 0x4>;
+			clkgate = <19>;
+			clkgate-seperated-reg;
+		};
+		gpioclk12: gpioclk12@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk12";
+			reg = <0xfc802020 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		gpioclk13: gpioclk13@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk13";
+			reg = <0xfc802020 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		gpioclk14: gpioclk14@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk14";
+			reg = <0xfc802020 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		gpioclk15: gpioclk15@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk15";
+			reg = <0xfc802020 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		gpioclk16: gpioclk16@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk16";
+			reg = <0xfc802020 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		gpioclk17: gpioclk17@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk17";
+			reg = <0xfc802020 0x4>;
+			clkgate = <25>;
+			clkgate-seperated-reg;
+		};
+		gpioclk18: gpioclk18@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk18";
+			reg = <0xfc802020 0x4>;
+			clkgate = <26>;
+			clkgate-seperated-reg;
+		};
+		gpioclk19: gpioclk19@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk19";
+			reg = <0xfc802020 0x4>;
+			clkgate = <27>;
+			clkgate-seperated-reg;
+		};
+		gpioclk20: gpioclk20@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk20";
+			reg = <0xfc802020 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		gpioclk21: gpioclk21@fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk21";
+			reg = <0xfc802020 0x4>;
+			clkgate = <29>;
+			clkgate-seperated-reg;
+		};
+		dphy0_clk: dphy0_clk@fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy0_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <15>;
+			clkgate-seperated-reg;
+		};
+		dphy1_clk: dphy1_clk@fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy1_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		dphy2_clk: dphy2_clk@fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy2_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		usbpicophy_clk: usbpicophy_clk@fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_pico>;
+			clock-output-names = "usbpicophy_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		acp_clk: acp_clk@fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "acp_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		timerclk45: timerclk45@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk45";
+			reg = <0xfc802040 0x4>;
+			clkgate = <3>;
+			clkgate-seperated-reg;
+		};
+		timerclk67: timerclk67@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk67";
+			reg = <0xfc802040 0x4>;
+			clkgate = <4>;
+			clkgate-seperated-reg;
+		};
+		timerclk89: timerclk89@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk89";
+			reg = <0xfc802040 0x4>;
+			clkgate = <5>;
+			clkgate-seperated-reg;
+		};
+		pwmclk0: pwmclk0@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pwm0_mux>;
+			clock-output-names = "pwmclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <7>;
+			clkgate-seperated-reg;
+		};
+		pwmclk1: pwmclk1@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pwm1_mux>;
+			clock-output-names = "pwmclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <8>;
+			clkgate-seperated-reg;
+		};
+		uartclk0: uartclk0@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart0_mux>;
+			clock-output-names = "uartclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		uartclk1: uartclk1@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart1_mux>;
+			clock-output-names = "uartclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		uartclk2: uartclk2@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart2_mux>;
+			clock-output-names = "uartclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <18>;
+			clkgate-seperated-reg;
+		};
+		uartclk3: uartclk3@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart3_mux>;
+			clock-output-names = "uartclk3";
+			reg = <0xfc802040 0x4>;
+			clkgate = <19>;
+			clkgate-seperated-reg;
+		};
+		uartclk4: uartclk4@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart4_mux>;
+			clock-output-names = "uartclk4";
+			reg = <0xfc802040 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		spiclk0: spiclk0@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi0_mux>;
+			clock-output-names = "spiclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		spiclk1: spiclk1@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi1_mux>;
+			clock-output-names = "spiclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		spiclk2: spiclk2@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi2_mux>;
+			clock-output-names = "spiclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		i2cclk0: i2cclk0@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		i2cclk1: i2cclk1@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <25>;
+			clkgate-seperated-reg;
+		};
+		sci_clk: sci_clk@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "sci_clk";
+			reg = <0xfc802040 0x4>;
+			clkgate = <26>;
+			clkgate-seperated-reg;
+		};
+		i2cclk2: i2cclk2@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		i2cclk3: i2cclk3@fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk3";
+			reg = <0xfc802040 0x4>;
+			clkgate = <29>;
+			clkgate-seperated-reg;
+		};
+		ddrc_per_clk: ddrc_per_clk@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "ddrc_per_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <9>;
+			clkgate-seperated-reg;
+		};
+		dmac_clk: dmac_clk@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "dmac_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		usb2dvc_clk: usb2dvc_clk@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "usb2dvc_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		sd_clk: sd_clk@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&sd_div>;
+			clock-output-names = "sd_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk1: mmc_clk1@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_mmc1_mux>;
+			clock-output-names = "mmc_clk1";
+			reg = <0xfc802050 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk2: mmc_clk2@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&mmc2_div>;
+			clock-output-names = "mmc_clk2";
+			reg = <0xfc802050 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk3: mmc_clk3@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&mmc3_div>;
+			clock-output-names = "mmc_clk3";
+			reg = <0xfc802050 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		mcu_clk: mcu_clk@fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&acp_clk>;
+			clock-output-names = "mcu_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 0000000..e05c65c
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,513 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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"
+
+/include/ "hi3620-clk.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		L2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0xfc10000 0x100000>;
+			interrupts = <0 15 4>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		gic: interrupt-controller@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>;
+		};
+
+		dual_timer0: dual_timer@fc800000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc800000 0x1000>;
+			/* timer00 & timer01 */
+			interrupts = <0 0 4>, <0 1 4>;
+			clocks = <&timer0_mux &timer1_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer1: dual_timer@fc801000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc801000 0x1000>;
+			/* timer10 & timer11 */
+			interrupts = <0 2 4>, <0 3 4>;
+			clocks = <&timer2_mux &timer3_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer2: dual_timer@fca01000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca01000 0x1000>;
+			/* timer20 & timer21 */
+			interrupts = <0 4 4>, <0 5 4>;
+			clocks = <&timer4_mux &timer5_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer3: dual_timer@fca02000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca02000 0x1000>;
+			/* timer30 & timer31 */
+			interrupts = <0 6 4>, <0 7 4>;
+			clocks = <&timer6_mux &timer7_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer4: dual_timer@fca03000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca03000 0x1000>;
+			/* timer40 & timer41 */
+			interrupts = <0 96 4>, <0 97 4>;
+			clocks = <&timer8_mux &timer9_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart0: uart@fcb00000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb00000 0x1000>;
+			interrupts = <0 20 4>;
+			clocks = <&uartclk0>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart1: uart@fcb01000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb01000 0x1000>;
+			interrupts = <0 21 4>;
+			clocks = <&uartclk1>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart2: uart@fcb02000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb02000 0x1000>;
+			interrupts = <0 22 4>;
+			clocks = <&uartclk2>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart3: uart@fcb03000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb03000 0x1000>;
+			interrupts = <0 23 4>;
+			clocks = <&uartclk3>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		uart4: uart@fcb04000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xfcb04000 0x1000>;
+			interrupts = <0 24 4>;
+			clocks = <&uartclk4>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		gpio0: gpio@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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..d45104e
--- /dev/null
+++ b/arch/arm/boot/dts/hi4511.dts
@@ -0,0 +1,648 @@
+/*
+ *  Copyright (C) 2012-2013 Linaro Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.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 earlyprintk";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
+
+	amba {
+		dual_timer0: dual_timer@fc800000 {
+			status = "ok";
+		};
+
+		uart0: uart@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@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@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@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@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@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@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 */
+		};
+	};
+};
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 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-clk.dtsi | 1052 +++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/hi3620.dtsi     |  513 ++++++++++++++++++
 arch/arm/boot/dts/hi4511.dts      |  648 +++++++++++++++++++++++
 4 files changed, 2214 insertions(+)
 create mode 100644 arch/arm/boot/dts/hi3620-clk.dtsi
 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 cc0f1fb..b4ec185 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
 	exynos5420-smdk5420.dtb \
 	exynos5440-sd5v1.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-clk.dtsi b/arch/arm/boot/dts/hi3620-clk.dtsi
new file mode 100644
index 0000000..51233d3
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620-clk.dtsi
@@ -0,0 +1,1052 @@
+/*
+ * 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.
+ */
+
+/ {
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		osc32k: osc32k {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "osc32khz";
+		};
+		osc26m: osc26m {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+			clock-output-names = "osc26mhz";
+		};
+		pclk: pclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+			clock-output-names = "apb_pclk";
+		};
+		pll_arm0: pll_arm0 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1600000000>;
+			clock-output-names = "armpll0";
+		};
+		pll_arm1: pll_arm1 {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1600000000>;
+			clock-output-names = "armpll1";
+		};
+		pll_peri: pll_peri {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1440000000>;
+			clock-output-names = "armpll2";
+		};
+		pll_usb: pll_usb {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1440000000>;
+			clock-output-names = "armpll3";
+		};
+		pll_hdmi: pll_hdmi {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1188000000>;
+			clock-output-names = "armpll4";
+		};
+		pll_gpu: pll_gpu {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <1300000000>;
+			clock-output-names = "armpll5";
+		};
+		rclk_tcxo: rclk_tcxo {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "rclk_tcxo";
+			clock-mult = <1>;
+			clock-div = <4>;
+		};
+		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>;
+		};
+		rclk_pico: rclk_pico {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+			clocks = <&hsic_div>;
+			clock-output-names = "rclk_pico";
+			clock-mult = <1>;
+			clock-div = <40>;
+		};
+
+		timer0_mux: timer0_mux at fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer0_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x18000>;
+			clkmux-table = <0 0x8000>;
+		};
+		timer1_mux: timer1_mux at fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk01>;
+			clock-output-names = "timer1_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x60000>;
+			clkmux-table = <0 0x20000>;
+		};
+		timer2_mux: timer2_mux at fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk23>;
+			clock-output-names = "timer2_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x180000>;
+			clkmux-table = <0 0x80000>;
+		};
+		timer3_mux: timer3_mux at fc802000 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk23>;
+			clock-output-names = "timer3_mux";
+			reg = <0xfc802000 0x4>;
+			clkmux-mask = <0x600000>;
+			clkmux-table = <0 0x200000>;
+		};
+		timer4_mux: timer4_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk45>;
+			clock-output-names = "timer4_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x3>;
+			clkmux-table = <0 0x1>;
+		};
+		timer5_mux: timer5_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk45>;
+			clock-output-names = "timer5_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc>;
+			clkmux-table = <0 0x4>;
+		};
+		timer6_mux: timer6_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk67>;
+			clock-output-names = "timer6_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x30>;
+			clkmux-table = <0 0x10>;
+		};
+		timer7_mux: timer7_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk67>;
+			clock-output-names = "timer7_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc0>;
+			clkmux-table = <0 0x40>;
+		};
+		timer8_mux: timer8_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk89>;
+			clock-output-names = "timer8_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0x300>;
+			clkmux-table = <0 0x100>;
+		};
+		timer9_mux: timer9_mux at fc802018 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &timerclk89>;
+			clock-output-names = "timer9_mux";
+			reg = <0xfc802018 0x4>;
+			clkmux-mask = <0xc00>;
+			clkmux-table = <0 0x400>;
+		};
+
+		uart0_mux: uart0_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x80>;
+			/* each item value */
+			clkmux-table = <0 0x80>;
+			clkmux-hiword-mask;
+		};
+		uart1_mux: uart1_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart1_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x100>;
+			clkmux-table = <0x0 0x100>;
+			clkmux-hiword-mask;
+		};
+		uart2_mux: uart2_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart2_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+		uart3_mux: uart3_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart3_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		uart4_mux: uart4_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &pclk>;
+			clock-output-names = "uart4_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		spi0_mux: spi0_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi0_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x1000>;
+			clkmux-table = <0 0x1000>;
+			clkmux-hiword-mask;
+		};
+		spi1_mux: spi1_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi1_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x2000>;
+			clkmux-table = <0 0x2000>;
+			clkmux-hiword-mask;
+		};
+		spi2_mux: spi2_mux at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &rclk_cfgaxi>;
+			clock-output-names = "spi2_mux";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x4000>;
+			clkmux-table = <0 0x4000>;
+			clkmux-hiword-mask;
+		};
+		rclk_shareAXI: rclk_shareAXI at fc802100 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "rclk_shareAXI";
+			reg = <0xfc802100 0x4>;
+			clkmux-mask = <0x8000>;
+			clkmux-table = <0 0x8000>;
+			clkmux-hiword-mask;
+		};
+		pwm0_mux: pwm0_mux at fc802104 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &osc26m>;
+			clock-output-names = "pwm0_mux";
+			reg = <0xfc802104 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		pwm1_mux: pwm1_mux at fc802104 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc32k &osc26m>;
+			clock-output-names = "pwm1_mux";
+			reg = <0xfc802104 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		sd_mux: sd_mux at fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "sd_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x10>;
+			clkmux-table = <0 0x10>;
+			clkmux-hiword-mask;
+		};
+		mmc1_mux: mmc1_mux at fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc1_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+		rclk_mmc1_mux: rclk_mmc1_mux at fc802108 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&osc26m &mmc1_div>;
+			clock-output-names = "rclk_mmc1_mux";
+			reg = <0xfc802108 0x4>;
+			clkmux-mask = <0x400>;
+			clkmux-table = <0 0x400>;
+			clkmux-hiword-mask;
+		};
+		g2d_mux: g2d_mux at fc80210c {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "g2d_mux";
+			reg = <0xfc80210c 0x4>;
+			clkmux-mask = <0x20>;
+			clkmux-table = <0 0x20>;
+			clkmux-hiword-mask;
+		};
+		venc_mux: venc_mux at fc80210c {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "venc_mux";
+			reg = <0xfc80210c 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		vdec_mux: vdec_mux at fc802110 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "vdec_mux";
+			reg = <0xfc802110 0x4>;
+			clkmux-mask = <0x20>;
+			clkmux-table = <0 0x20>;
+			clkmux-hiword-mask;
+		};
+		vpp_mux: vpp_mux at fc802110 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "vpp_mux";
+			reg = <0xfc802110 0x4>;
+			clkmux-mask = <0x800>;
+			clkmux-table = <0 0x800>;
+			clkmux-hiword-mask;
+		};
+		edc0_mux: edc0_mux at fc802114 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "edc0_mux";
+			reg = <0xfc802114 0x4>;
+			clkmux-mask = <0x40>;
+			clkmux-table = <0 0x40>;
+			clkmux-hiword-mask;
+		};
+		ldi0_mux: ldi0_mux at fc802114 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_hdmi &pll_usb &pll_gpu>;
+			clock-output-names = "ldi0_mux";
+			reg = <0xfc802114 0x4>;
+			clkmux-mask = <0x6000>;
+			clkmux-table = <0 0x2000 0x4000 0x6000>;
+			clkmux-hiword-mask;
+		};
+		edc1_mux: edc1_mux at fc802118 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_usb>;
+			clock-output-names = "edc1_mux";
+			reg = <0xfc802118 0x4>;
+			clkmux-mask = <0x40>;
+			clkmux-table = <0 0x40>;
+			clkmux-hiword-mask;
+		};
+		ldi1_mux: ldi1_mux at fc802118 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_peri &pll_hdmi &pll_usb &pll_gpu>;
+			clock-output-names = "ldi1_mux";
+			reg = <0xfc802118 0x4>;
+			clkmux-mask = <0xc000>;
+			clkmux-table = <0 0x4000 0x8000 0xc000>;
+			clkmux-hiword-mask;
+		};
+		rclk_hsic: rclk_hsic at fc802130 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "rclk_hsic";
+			reg = <0xfc802130 0x4>;
+			clkmux-mask = <0x4>;
+			clkmux-table = <0 0x4>;
+			clkmux-hiword-mask;
+		};
+		mmc2_mux: mmc2_mux at fc802140 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc2_mux";
+			reg = <0xfc802140 0x4>;
+			clkmux-mask = <0x10>;
+			clkmux-table = <0 0x10>;
+			clkmux-hiword-mask;
+		};
+		mmc3_mux: mmc3_mux at fc802140 {
+			compatible = "hisilicon,clk-mux";
+			#clock-cells = <0>;
+			clocks = <&pll_usb &pll_peri>;
+			clock-output-names = "mmc3_mux";
+			reg = <0xfc802140 0x4>;
+			clkmux-mask = <0x200>;
+			clkmux-table = <0 0x200>;
+			clkmux-hiword-mask;
+		};
+
+		shareaxi_div: shareaxi_div at fc802100 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&rclk_shareAXI>;
+			clock-output-names = "shareaxi_div";
+			reg = <0xfc802100 0x4>;
+			clkdiv-mask = <0x1f>;
+			clkdiv-min = <1>;
+			clkdiv-max = <32>;
+			clkdiv-hiword-mask;
+		};
+		cfgaxi_div: cfgaxi_div at fc802100 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&shareaxi_div>;
+			clock-output-names = "cfgaxi_div";
+			reg = <0xfc802100 0x4>;
+			clkdiv-mask = <0x60>;
+			clkdiv-min = <2>;
+			clkdiv-max = <2>;
+			clkdiv-hiword-mask;
+		};
+		sd_div: sd_div at fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&sd_mux>;
+			clock-output-names = "sd_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0xf>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		mmc1_div: mmc1_div at fc802108 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc1_div";
+			reg = <0xfc802108 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		hsic_div: hsic_div at fc802130 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&rclk_hsic>;
+			clock-output-names = "hsic_div";
+			reg = <0xfc802130 0x4>;
+			clkdiv-mask = <0x3>;
+			clkdiv-min = <1>;
+			clkdiv-max = <4>;
+			clkdiv-hiword-mask;
+		};
+		mmc2_div: mmc2_div at fc802140 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc2_div";
+			reg = <0xfc802140 0x4>;
+			clkdiv-mask = <0xf>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+		mmc3_div: mmc3_div at fc802140 {
+			compatible = "hisilicon,clk-div";
+			#clock-cells = <0>;
+			clocks = <&mmc1_mux>;
+			clock-output-names = "mmc3_div";
+			reg = <0xfc802140 0x4>;
+			clkdiv-mask = <0x1e0>;
+			clkdiv-min = <1>;
+			clkdiv-max = <16>;
+			clkdiv-hiword-mask;
+		};
+
+		timerclk01: timerclk01 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk01>;
+			clock-output-names = "timerclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <0>;
+			clkgate-seperated-reg;
+		};
+		timer_rclk01: timer_rclk01 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timer_rclk01";
+			reg = <0xfc802020 0x4>;
+			clkgate = <1>;
+			clkgate-seperated-reg;
+		};
+		timerclk23: timerclk23 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&timer_rclk23>;
+			clock-output-names = "timerclk23";
+			reg = <0xfc802020 0x4>;
+			clkgate = <2>;
+			clkgate-seperated-reg;
+		};
+		timer_rclk23: timer_rclk23 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timer_rclk23";
+			reg = <0xfc802020 0x4>;
+			clkgate = <3>;
+			clkgate-seperated-reg;
+		};
+		rtcclk: rtcclk at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "rtcclk";
+			reg = <0xfc802020 0x4>;
+			clkgate = <5>;
+			clkgate-seperated-reg;
+		};
+		kpc_clk: kpc_clk at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "kpc_clk";
+			reg = <0xfc802020 0x4>;
+			clkgate = <6>;
+			clkgate-seperated-reg;
+		};
+		gpioclk0: gpioclk0 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk0";
+			reg = <0xfc802020 0x4>;
+			clkgate = <8>;
+			clkgate-seperated-reg;
+		};
+		gpioclk1: gpioclk1 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk1";
+			reg = <0xfc802020 0x4>;
+			clkgate = <9>;
+			clkgate-seperated-reg;
+		};
+		gpioclk2: gpioclk2 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk2";
+			reg = <0xfc802020 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		gpioclk3: gpioclk3 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk3";
+			reg = <0xfc802020 0x4>;
+			clkgate = <11>;
+			clkgate-seperated-reg;
+		};
+		gpioclk4: gpioclk4 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk4";
+			reg = <0xfc802020 0x4>;
+			clkgate = <12>;
+			clkgate-seperated-reg;
+		};
+		gpioclk5: gpioclk5 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk5";
+			reg = <0xfc802020 0x4>;
+			clkgate = <13>;
+			clkgate-seperated-reg;
+		};
+		gpioclk6: gpioclk6 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk6";
+			reg = <0xfc802020 0x4>;
+			clkgate = <14>;
+			clkgate-seperated-reg;
+		};
+		gpioclk7: gpioclk7 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk7";
+			reg = <0xfc802020 0x4>;
+			clkgate = <15>;
+			clkgate-seperated-reg;
+		};
+		gpioclk8: gpioclk8 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk8";
+			reg = <0xfc802020 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		gpioclk9: gpioclk9 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk9";
+			reg = <0xfc802020 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		gpioclk10: gpioclk10 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk10";
+			reg = <0xfc802020 0x4>;
+			clkgate = <18>;
+			clkgate-seperated-reg;
+		};
+		gpioclk11: gpioclk11 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk11";
+			reg = <0xfc802020 0x4>;
+			clkgate = <19>;
+			clkgate-seperated-reg;
+		};
+		gpioclk12: gpioclk12 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk12";
+			reg = <0xfc802020 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		gpioclk13: gpioclk13 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk13";
+			reg = <0xfc802020 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		gpioclk14: gpioclk14 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk14";
+			reg = <0xfc802020 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		gpioclk15: gpioclk15 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk15";
+			reg = <0xfc802020 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		gpioclk16: gpioclk16 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk16";
+			reg = <0xfc802020 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		gpioclk17: gpioclk17 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk17";
+			reg = <0xfc802020 0x4>;
+			clkgate = <25>;
+			clkgate-seperated-reg;
+		};
+		gpioclk18: gpioclk18 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk18";
+			reg = <0xfc802020 0x4>;
+			clkgate = <26>;
+			clkgate-seperated-reg;
+		};
+		gpioclk19: gpioclk19 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk19";
+			reg = <0xfc802020 0x4>;
+			clkgate = <27>;
+			clkgate-seperated-reg;
+		};
+		gpioclk20: gpioclk20 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk20";
+			reg = <0xfc802020 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		gpioclk21: gpioclk21 at fc802020 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "gpioclk21";
+			reg = <0xfc802020 0x4>;
+			clkgate = <29>;
+			clkgate-seperated-reg;
+		};
+		dphy0_clk: dphy0_clk at fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy0_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <15>;
+			clkgate-seperated-reg;
+		};
+		dphy1_clk: dphy1_clk at fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy1_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		dphy2_clk: dphy2_clk at fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "dphy2_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		usbpicophy_clk: usbpicophy_clk at fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_pico>;
+			clock-output-names = "usbpicophy_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		acp_clk: acp_clk at fc802030 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "acp_clk";
+			reg = <0xfc802030 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		timerclk45: timerclk45 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk45";
+			reg = <0xfc802040 0x4>;
+			clkgate = <3>;
+			clkgate-seperated-reg;
+		};
+		timerclk67: timerclk67 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk67";
+			reg = <0xfc802040 0x4>;
+			clkgate = <4>;
+			clkgate-seperated-reg;
+		};
+		timerclk89: timerclk89 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_tcxo>;
+			clock-output-names = "timerclk89";
+			reg = <0xfc802040 0x4>;
+			clkgate = <5>;
+			clkgate-seperated-reg;
+		};
+		pwmclk0: pwmclk0 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pwm0_mux>;
+			clock-output-names = "pwmclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <7>;
+			clkgate-seperated-reg;
+		};
+		pwmclk1: pwmclk1 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pwm1_mux>;
+			clock-output-names = "pwmclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <8>;
+			clkgate-seperated-reg;
+		};
+		uartclk0: uartclk0 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart0_mux>;
+			clock-output-names = "uartclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <16>;
+			clkgate-seperated-reg;
+		};
+		uartclk1: uartclk1 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart1_mux>;
+			clock-output-names = "uartclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <17>;
+			clkgate-seperated-reg;
+		};
+		uartclk2: uartclk2 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart2_mux>;
+			clock-output-names = "uartclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <18>;
+			clkgate-seperated-reg;
+		};
+		uartclk3: uartclk3 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart3_mux>;
+			clock-output-names = "uartclk3";
+			reg = <0xfc802040 0x4>;
+			clkgate = <19>;
+			clkgate-seperated-reg;
+		};
+		uartclk4: uartclk4 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&uart4_mux>;
+			clock-output-names = "uartclk4";
+			reg = <0xfc802040 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		spiclk0: spiclk0 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi0_mux>;
+			clock-output-names = "spiclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		spiclk1: spiclk1 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi1_mux>;
+			clock-output-names = "spiclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		spiclk2: spiclk2 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&spi2_mux>;
+			clock-output-names = "spiclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		i2cclk0: i2cclk0 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk0";
+			reg = <0xfc802040 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+		i2cclk1: i2cclk1 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk1";
+			reg = <0xfc802040 0x4>;
+			clkgate = <25>;
+			clkgate-seperated-reg;
+		};
+		sci_clk: sci_clk at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&osc26m>;
+			clock-output-names = "sci_clk";
+			reg = <0xfc802040 0x4>;
+			clkgate = <26>;
+			clkgate-seperated-reg;
+		};
+		i2cclk2: i2cclk2 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk2";
+			reg = <0xfc802040 0x4>;
+			clkgate = <28>;
+			clkgate-seperated-reg;
+		};
+		i2cclk3: i2cclk3 at fc802040 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&pclk>;
+			clock-output-names = "i2cclk3";
+			reg = <0xfc802040 0x4>;
+			clkgate = <29>;
+			clkgate-seperated-reg;
+		};
+		ddrc_per_clk: ddrc_per_clk at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "ddrc_per_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <9>;
+			clkgate-seperated-reg;
+		};
+		dmac_clk: dmac_clk at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "dmac_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		usb2dvc_clk: usb2dvc_clk at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_cfgaxi>;
+			clock-output-names = "usb2dvc_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <10>;
+			clkgate-seperated-reg;
+		};
+		sd_clk: sd_clk at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&sd_div>;
+			clock-output-names = "sd_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <20>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk1: mmc_clk1 at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&rclk_mmc1_mux>;
+			clock-output-names = "mmc_clk1";
+			reg = <0xfc802050 0x4>;
+			clkgate = <21>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk2: mmc_clk2 at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&mmc2_div>;
+			clock-output-names = "mmc_clk2";
+			reg = <0xfc802050 0x4>;
+			clkgate = <22>;
+			clkgate-seperated-reg;
+		};
+		mmc_clk3: mmc_clk3 at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&mmc3_div>;
+			clock-output-names = "mmc_clk3";
+			reg = <0xfc802050 0x4>;
+			clkgate = <23>;
+			clkgate-seperated-reg;
+		};
+		mcu_clk: mcu_clk at fc802050 {
+			compatible = "hisilicon,clk-gate";
+			#clock-cells = <0>;
+			clocks = <&acp_clk>;
+			clock-output-names = "mcu_clk";
+			reg = <0xfc802050 0x4>;
+			clkgate = <24>;
+			clkgate-seperated-reg;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 0000000..e05c65c
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,513 @@
+/*
+ * 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"
+
+/include/ "hi3620-clk.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		L2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0xfc10000 0x100000>;
+			interrupts = <0 15 4>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		gic: 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>;
+		};
+
+		dual_timer0: dual_timer at fc800000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc800000 0x1000>;
+			/* timer00 & timer01 */
+			interrupts = <0 0 4>, <0 1 4>;
+			clocks = <&timer0_mux &timer1_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer1: dual_timer at fc801000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc801000 0x1000>;
+			/* timer10 & timer11 */
+			interrupts = <0 2 4>, <0 3 4>;
+			clocks = <&timer2_mux &timer3_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer2: dual_timer at fca01000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca01000 0x1000>;
+			/* timer20 & timer21 */
+			interrupts = <0 4 4>, <0 5 4>;
+			clocks = <&timer4_mux &timer5_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer3: dual_timer at fca02000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca02000 0x1000>;
+			/* timer30 & timer31 */
+			interrupts = <0 6 4>, <0 7 4>;
+			clocks = <&timer6_mux &timer7_mux>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		dual_timer4: dual_timer at fca03000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca03000 0x1000>;
+			/* timer40 & timer41 */
+			interrupts = <0 96 4>, <0 97 4>;
+			clocks = <&timer8_mux &timer9_mux>;
+			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..d45104e
--- /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 earlyprintk";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
+
+	amba {
+		dual_timer0: dual_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 */
+		};
+	};
+};
-- 
1.8.1.2

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

* [PATCH v10 4/7] ARM: config: enable hi3xxx in multi_v7_defconfig
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Enable ARCH_HI3xxx in multi_v7_defconfig.

Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6e572c6..6855397 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -8,6 +8,7 @@ CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_BCM=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_HI3xxx=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_IMX51_DT=y
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 4/7] ARM: config: enable hi3xxx in multi_v7_defconfig
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Enable ARCH_HI3xxx in multi_v7_defconfig.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6e572c6..6855397 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -8,6 +8,7 @@ CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_BCM=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_HI3xxx=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_IMX51_DT=y
-- 
1.8.1.2

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

* [PATCH v10 5/7] ARM: config: add defconfig for Hi3xxx
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Add default config for arch-hi3xxx. It's used for Hisilicon Hi3xxx SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/configs/hi3xxx_defconfig | 56 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 arch/arm/configs/hi3xxx_defconfig

diff --git a/arch/arm/configs/hi3xxx_defconfig b/arch/arm/configs/hi3xxx_defconfig
new file mode 100644
index 0000000..f186bdf
--- /dev/null
+++ b/arch/arm/configs/hi3xxx_defconfig
@@ -0,0 +1,56 @@
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_ARCH_HI3xxx=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_DRM=y
+CONFIG_FB_SIMPLE=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_PL330_DMA=y
+CONFIG_PWM=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 5/7] ARM: config: add defconfig for Hi3xxx
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Add default config for arch-hi3xxx. It's used for Hisilicon Hi3xxx SoC.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/configs/hi3xxx_defconfig | 56 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 arch/arm/configs/hi3xxx_defconfig

diff --git a/arch/arm/configs/hi3xxx_defconfig b/arch/arm/configs/hi3xxx_defconfig
new file mode 100644
index 0000000..f186bdf
--- /dev/null
+++ b/arch/arm/configs/hi3xxx_defconfig
@@ -0,0 +1,56 @@
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_ARCH_HI3xxx=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_DRM=y
+CONFIG_FB_SIMPLE=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_PL330_DMA=y
+CONFIG_PWM=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
-- 
1.8.1.2

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

* [PATCH v10 6/7] ARM: hi3xxx: add smp support
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Zhangfei Gao, Haojian Zhuang

From: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Enable SMP support on hi3xxx platform

Signed-off-by: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Tested-by: Zhang Mingjun <zhang.mingjun-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Tested-by: Li Xin <li.xin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../bindings/arm/hisilicon/hisilicon.txt           | 30 ++++++--
 arch/arm/boot/dts/hi3620.dtsi                      | 38 ++++++++++
 arch/arm/mach-hi3xxx/Kconfig                       |  3 +
 arch/arm/mach-hi3xxx/Makefile                      |  1 +
 arch/arm/mach-hi3xxx/core.h                        | 11 +++
 arch/arm/mach-hi3xxx/hi3xxx.c                      | 34 +++++++++
 arch/arm/mach-hi3xxx/platsmp.c                     | 84 ++++++++++++++++++++++
 7 files changed, 197 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/mach-hi3xxx/core.h
 create mode 100644 arch/arm/mach-hi3xxx/platsmp.c

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index 3be60c8..8c7a465 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -1,10 +1,32 @@
 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";
+
+Hisilicon system controller
+
+Required properties:
+- compatible : "hisilicon,sysctrl"
+- reg : Register address and size
+
+Optional properties:
+- smp-offset : offset in sysctrl for notifying slave cpu booting
+		cpu 1, reg;
+		cpu 2, reg + 0x4;
+		cpu 3, reg + 0x8;
+		If reg value is not zero, cpun exit wfi and go
+- resume-offset : offset in sysctrl for notifying cpu0 when resume
+- reboot-offset : offset in sysctrl for system reboot
+
+Example:
+
+	/* for Hi3620 */
+	sysctrl: system-controller@fc802000 {
+		compatible = "hisilicon,sysctrl";
+		reg = <0xfc802000 0x1000>;
+		smp-offset = <0x31c>;
+		resume-offset = <0x308>;
+		reboot-offset = <0x4>;
+	};
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
index e05c65c..69640ea 100644
--- a/arch/arm/boot/dts/hi3620.dtsi
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -34,6 +34,27 @@
 			reg = <0x0>;
 			next-level-cache = <&L2>;
 		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <2>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu@3 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <3>;
+			next-level-cache = <&L2>;
+		};
 	};
 
 	amba {
@@ -60,6 +81,17 @@
 			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
 		};
 
+		sysctrl: system-controller@fc802000 {
+			compatible = "hisilicon,sysctrl";
+			reg = <0xfc802000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			smp-offset = <0x31c>;
+			resume-offset = <0x308>;
+			reboot-offset = <0x4>;
+		};
+
 		dual_timer0: dual_timer@fc800000 {
 			compatible = "arm,sp804", "arm,primecell";
 			reg = <0xfc800000 0x1000>;
@@ -110,6 +142,12 @@
 			status = "disabled";
 		};
 
+		timer5: timer@fc000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0xfc000600 0x20>;
+			interrupts = <1 13 0xf01>;
+		};
+
 		uart0: uart@fcb00000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0xfcb00000 0x1000>;
diff --git a/arch/arm/mach-hi3xxx/Kconfig b/arch/arm/mach-hi3xxx/Kconfig
index 68bd26c..d0f298a 100644
--- a/arch/arm/mach-hi3xxx/Kconfig
+++ b/arch/arm/mach-hi3xxx/Kconfig
@@ -6,6 +6,9 @@ config ARCH_HI3xxx
 	select CACHE_L2X0
 	select CLKSRC_OF
 	select GENERIC_CLOCKEVENTS
+	select HAVE_ARM_SCU
+	select HAVE_ARM_TWD
+	select HAVE_SMP
 	select PINCTRL
 	select PINCTRL_SINGLE
 	help
diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
index d68ebb3..7a869a7 100644
--- a/arch/arm/mach-hi3xxx/Makefile
+++ b/arch/arm/mach-hi3xxx/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-y	+= hi3xxx.o
+obj-$(CONFIG_SMP)		+= platsmp.o
diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h
new file mode 100644
index 0000000..226f020
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/core.h
@@ -0,0 +1,11 @@
+#ifndef __HISILICON_CORE_H
+#define __HISILICON_CORE_H
+
+#include <linux/reboot.h>
+
+extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
+extern int hi3xxx_get_cpu_jump(int cpu);
+extern void secondary_startup(void);
+extern struct smp_operations hi3xxx_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-hi3xxx/hi3xxx.c b/arch/arm/mach-hi3xxx/hi3xxx.c
index 4220860..d7cd6e4 100644
--- a/arch/arm/mach-hi3xxx/hi3xxx.c
+++ b/arch/arm/mach-hi3xxx/hi3xxx.c
@@ -14,13 +14,19 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/irqchip.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include "core.h"
+
 static struct map_desc hi3620_io_desc[] __initdata = {
 	{
+		/* sysctrl */
 		.pfn		= __phys_to_pfn(0xfc802000),
 		.virtual	= 0xfe802000,
 		.length		= 0x1000,
@@ -40,6 +46,32 @@ static void __init hi3xxx_timer_init(void)
 	clocksource_of_init();
 }
 
+static void hi3xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int offset;
+
+	np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+	if (!np) {
+		pr_err("failed to find hisilicon,sysctrl node\n");
+		return;
+	}
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("failed to map address in hisilicon,sysctrl node\n");
+		return;
+	}
+	if (of_property_read_u32(np, "reboot-offset", &offset) < 0) {
+		pr_err("failed to find reboot-offset property\n");
+		return;
+	}
+	writel_relaxed(0xdeadbeef, base + offset);
+
+	while (1)
+		cpu_do_idle();
+}
+
 static const char *hi3xxx_compat[] __initdata = {
 	"hisilicon,hi3620-hi4511",
 	NULL,
@@ -49,4 +81,6 @@ DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
 	.map_io		= hi3620_map_io,
 	.init_time	= hi3xxx_timer_init,
 	.dt_compat	= hi3xxx_compat,
+	.smp		= smp_ops(hi3xxx_smp_ops),
+	.restart	= hi3xxx_restart,
 MACHINE_END
diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c
new file mode 100644
index 0000000..a4d04c0
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/platsmp.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "core.h"
+
+static void __iomem *ctrl_base = NULL;
+
+void hi3xxx_set_cpu_jump(int cpu, void *jump_addr)
+{
+	cpu = cpu_logical_map(cpu);
+	if (!cpu || !ctrl_base)
+		return;
+	writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2));
+}
+
+int hi3xxx_get_cpu_jump(int cpu)
+{
+	cpu = cpu_logical_map(cpu);
+	if (!cpu || !ctrl_base)
+		return 0;
+	return readl_relaxed(ctrl_base + ((cpu - 1 ) << 2));
+}
+
+static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *np = NULL;
+	unsigned long base = 0;
+	u32 offset = 0;
+	void __iomem *scu_base = NULL;
+
+	if (scu_a9_has_base()) {
+		base = scu_a9_get_base();
+		scu_base = ioremap(base, SZ_4K);
+		if (!scu_base) {
+			pr_err("ioremap(scu_base) failed\n");
+			return;
+		}
+		scu_enable(scu_base);
+		iounmap(scu_base);
+	}
+	if (!ctrl_base) {
+		np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+		if (!np) {
+			pr_err("failed to find hisilicon,sysctrl node\n");
+			return;
+		}
+		ctrl_base = of_iomap(np, 0);
+		if (!ctrl_base) {
+			pr_err("failed to map address\n");
+			return;
+		}
+		if (of_property_read_u32(np, "smp-offset", &offset) < 0) {
+			pr_err("failed to find smp-offset property\n");
+			return;
+		}
+		ctrl_base += offset;
+	}
+}
+
+static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	hi3xxx_set_cpu_jump(cpu, secondary_startup);
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	return 0;
+}
+
+struct smp_operations hi3xxx_smp_ops __initdata = {
+	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
+	.smp_boot_secondary	= hi3xxx_boot_secondary,
+};
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 6/7] ARM: hi3xxx: add smp support
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Zhangfei Gao <zhangfei.gao@linaro.org>

Enable SMP support on hi3xxx platform

Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Tested-by: Zhang Mingjun <zhang.mingjun@linaro.org>
Tested-by: Li Xin <li.xin@linaro.org>
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../bindings/arm/hisilicon/hisilicon.txt           | 30 ++++++--
 arch/arm/boot/dts/hi3620.dtsi                      | 38 ++++++++++
 arch/arm/mach-hi3xxx/Kconfig                       |  3 +
 arch/arm/mach-hi3xxx/Makefile                      |  1 +
 arch/arm/mach-hi3xxx/core.h                        | 11 +++
 arch/arm/mach-hi3xxx/hi3xxx.c                      | 34 +++++++++
 arch/arm/mach-hi3xxx/platsmp.c                     | 84 ++++++++++++++++++++++
 7 files changed, 197 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/mach-hi3xxx/core.h
 create mode 100644 arch/arm/mach-hi3xxx/platsmp.c

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index 3be60c8..8c7a465 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -1,10 +1,32 @@
 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";
+
+Hisilicon system controller
+
+Required properties:
+- compatible : "hisilicon,sysctrl"
+- reg : Register address and size
+
+Optional properties:
+- smp-offset : offset in sysctrl for notifying slave cpu booting
+		cpu 1, reg;
+		cpu 2, reg + 0x4;
+		cpu 3, reg + 0x8;
+		If reg value is not zero, cpun exit wfi and go
+- resume-offset : offset in sysctrl for notifying cpu0 when resume
+- reboot-offset : offset in sysctrl for system reboot
+
+Example:
+
+	/* for Hi3620 */
+	sysctrl: system-controller at fc802000 {
+		compatible = "hisilicon,sysctrl";
+		reg = <0xfc802000 0x1000>;
+		smp-offset = <0x31c>;
+		resume-offset = <0x308>;
+		reboot-offset = <0x4>;
+	};
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
index e05c65c..69640ea 100644
--- a/arch/arm/boot/dts/hi3620.dtsi
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -34,6 +34,27 @@
 			reg = <0x0>;
 			next-level-cache = <&L2>;
 		};
+
+		cpu at 1 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu at 2 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <2>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu at 3 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <3>;
+			next-level-cache = <&L2>;
+		};
 	};
 
 	amba {
@@ -60,6 +81,17 @@
 			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
 		};
 
+		sysctrl: system-controller at fc802000 {
+			compatible = "hisilicon,sysctrl";
+			reg = <0xfc802000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			smp-offset = <0x31c>;
+			resume-offset = <0x308>;
+			reboot-offset = <0x4>;
+		};
+
 		dual_timer0: dual_timer at fc800000 {
 			compatible = "arm,sp804", "arm,primecell";
 			reg = <0xfc800000 0x1000>;
@@ -110,6 +142,12 @@
 			status = "disabled";
 		};
 
+		timer5: timer at fc000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0xfc000600 0x20>;
+			interrupts = <1 13 0xf01>;
+		};
+
 		uart0: uart at fcb00000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0xfcb00000 0x1000>;
diff --git a/arch/arm/mach-hi3xxx/Kconfig b/arch/arm/mach-hi3xxx/Kconfig
index 68bd26c..d0f298a 100644
--- a/arch/arm/mach-hi3xxx/Kconfig
+++ b/arch/arm/mach-hi3xxx/Kconfig
@@ -6,6 +6,9 @@ config ARCH_HI3xxx
 	select CACHE_L2X0
 	select CLKSRC_OF
 	select GENERIC_CLOCKEVENTS
+	select HAVE_ARM_SCU
+	select HAVE_ARM_TWD
+	select HAVE_SMP
 	select PINCTRL
 	select PINCTRL_SINGLE
 	help
diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
index d68ebb3..7a869a7 100644
--- a/arch/arm/mach-hi3xxx/Makefile
+++ b/arch/arm/mach-hi3xxx/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-y	+= hi3xxx.o
+obj-$(CONFIG_SMP)		+= platsmp.o
diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h
new file mode 100644
index 0000000..226f020
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/core.h
@@ -0,0 +1,11 @@
+#ifndef __HISILICON_CORE_H
+#define __HISILICON_CORE_H
+
+#include <linux/reboot.h>
+
+extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
+extern int hi3xxx_get_cpu_jump(int cpu);
+extern void secondary_startup(void);
+extern struct smp_operations hi3xxx_smp_ops;
+
+#endif
diff --git a/arch/arm/mach-hi3xxx/hi3xxx.c b/arch/arm/mach-hi3xxx/hi3xxx.c
index 4220860..d7cd6e4 100644
--- a/arch/arm/mach-hi3xxx/hi3xxx.c
+++ b/arch/arm/mach-hi3xxx/hi3xxx.c
@@ -14,13 +14,19 @@
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
 #include <linux/irqchip.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include "core.h"
+
 static struct map_desc hi3620_io_desc[] __initdata = {
 	{
+		/* sysctrl */
 		.pfn		= __phys_to_pfn(0xfc802000),
 		.virtual	= 0xfe802000,
 		.length		= 0x1000,
@@ -40,6 +46,32 @@ static void __init hi3xxx_timer_init(void)
 	clocksource_of_init();
 }
 
+static void hi3xxx_restart(enum reboot_mode mode, const char *cmd)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int offset;
+
+	np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+	if (!np) {
+		pr_err("failed to find hisilicon,sysctrl node\n");
+		return;
+	}
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("failed to map address in hisilicon,sysctrl node\n");
+		return;
+	}
+	if (of_property_read_u32(np, "reboot-offset", &offset) < 0) {
+		pr_err("failed to find reboot-offset property\n");
+		return;
+	}
+	writel_relaxed(0xdeadbeef, base + offset);
+
+	while (1)
+		cpu_do_idle();
+}
+
 static const char *hi3xxx_compat[] __initdata = {
 	"hisilicon,hi3620-hi4511",
 	NULL,
@@ -49,4 +81,6 @@ DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)")
 	.map_io		= hi3620_map_io,
 	.init_time	= hi3xxx_timer_init,
 	.dt_compat	= hi3xxx_compat,
+	.smp		= smp_ops(hi3xxx_smp_ops),
+	.restart	= hi3xxx_restart,
 MACHINE_END
diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c
new file mode 100644
index 0000000..a4d04c0
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/platsmp.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "core.h"
+
+static void __iomem *ctrl_base = NULL;
+
+void hi3xxx_set_cpu_jump(int cpu, void *jump_addr)
+{
+	cpu = cpu_logical_map(cpu);
+	if (!cpu || !ctrl_base)
+		return;
+	writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2));
+}
+
+int hi3xxx_get_cpu_jump(int cpu)
+{
+	cpu = cpu_logical_map(cpu);
+	if (!cpu || !ctrl_base)
+		return 0;
+	return readl_relaxed(ctrl_base + ((cpu - 1 ) << 2));
+}
+
+static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *np = NULL;
+	unsigned long base = 0;
+	u32 offset = 0;
+	void __iomem *scu_base = NULL;
+
+	if (scu_a9_has_base()) {
+		base = scu_a9_get_base();
+		scu_base = ioremap(base, SZ_4K);
+		if (!scu_base) {
+			pr_err("ioremap(scu_base) failed\n");
+			return;
+		}
+		scu_enable(scu_base);
+		iounmap(scu_base);
+	}
+	if (!ctrl_base) {
+		np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+		if (!np) {
+			pr_err("failed to find hisilicon,sysctrl node\n");
+			return;
+		}
+		ctrl_base = of_iomap(np, 0);
+		if (!ctrl_base) {
+			pr_err("failed to map address\n");
+			return;
+		}
+		if (of_property_read_u32(np, "smp-offset", &offset) < 0) {
+			pr_err("failed to find smp-offset property\n");
+			return;
+		}
+		ctrl_base += offset;
+	}
+}
+
+static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	hi3xxx_set_cpu_jump(cpu, secondary_startup);
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	return 0;
+}
+
+struct smp_operations hi3xxx_smp_ops __initdata = {
+	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
+	.smp_boot_secondary	= hi3xxx_boot_secondary,
+};
-- 
1.8.1.2

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

* [PATCH v10 7/7] ARM: hi3xxx: add hotplug support
  2013-10-15  9:16 ` Haojian Zhuang
@ 2013-10-15  9:16     ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Zhangfei Gao, Haojian Zhuang

From: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Enable hotplug support on hi3xxx platform

How to test:
cat proc/interrupts
echo 0 > /sys/devices/system/cpu/cpuX/online
cat proc/interrupts
echo 1 > /sys/devices/system/cpu/cpuX/online

Signed-off-by: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Tested-by: Zhang Mingjun <zhang.mingjun-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/mach-hi3xxx/Makefile  |   1 +
 arch/arm/mach-hi3xxx/core.h    |   4 +
 arch/arm/mach-hi3xxx/hotplug.c | 200 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-hi3xxx/platsmp.c |   5 ++
 4 files changed, 210 insertions(+)
 create mode 100644 arch/arm/mach-hi3xxx/hotplug.c

diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
index 7a869a7..c9919e8 100644
--- a/arch/arm/mach-hi3xxx/Makefile
+++ b/arch/arm/mach-hi3xxx/Makefile
@@ -4,3 +4,4 @@
 
 obj-y	+= hi3xxx.o
 obj-$(CONFIG_SMP)		+= platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h
index 226f020..af23ec2 100644
--- a/arch/arm/mach-hi3xxx/core.h
+++ b/arch/arm/mach-hi3xxx/core.h
@@ -8,4 +8,8 @@ extern int hi3xxx_get_cpu_jump(int cpu);
 extern void secondary_startup(void);
 extern struct smp_operations hi3xxx_smp_ops;
 
+extern void hi3xxx_cpu_die(unsigned int cpu);
+extern int hi3xxx_cpu_kill(unsigned int cpu);
+extern void hi3xxx_set_cpu(int cpu, bool enable);
+
 #endif
diff --git a/arch/arm/mach-hi3xxx/hotplug.c b/arch/arm/mach-hi3xxx/hotplug.c
new file mode 100644
index 0000000..5dc949e
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/hotplug.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "core.h"
+
+/* Sysctrl registers in Hi3620 SoC */
+#define SCISOEN				0xc0
+#define SCISODIS			0xc4
+#define SCPERPWREN			0xd0
+#define SCPERPWRDIS			0xd4
+#define SCCPUCOREEN			0xf4
+#define SCCPUCOREDIS			0xf8
+#define SCPERCTRL0			0x200
+#define SCCPURSTEN			0x410
+#define SCCPURSTDIS			0x414
+
+/*
+ * bit definition in SCISOEN/SCPERPWREN/...
+ *
+ * CPU2_ISO_CTRL	(1 << 5)
+ * CPU3_ISO_CTRL	(1 << 6)
+ * ...
+ */
+#define CPU2_ISO_CTRL			(1 << 5)
+
+/*
+ * bit definition in SCPERCTRL0
+ *
+ * CPU0_WFI_MASK_CFG	(1 << 28)
+ * CPU1_WFI_MASK_CFG	(1 << 29)
+ * ...
+ */
+#define CPU0_WFI_MASK_CFG		(1 << 28)
+
+/*
+ * bit definition in SCCPURSTEN/...
+ *
+ * CPU0_SRST_REQ_EN	(1 << 0)
+ * CPU1_SRST_REQ_EN	(1 << 1)
+ * ...
+ */
+#define CPU0_HPM_SRST_REQ_EN		(1 << 22)
+#define CPU0_DBG_SRST_REQ_EN		(1 << 12)
+#define CPU0_NEON_SRST_REQ_EN		(1 << 4)
+#define CPU0_SRST_REQ_EN		(1 << 0)
+
+enum {
+	HI3620_CTRL,
+	ERROR_CTRL,
+};
+
+static void __iomem *ctrl_base = NULL;
+static int id;
+
+static void set_cpu_hi3620(int cpu, bool enable)
+{
+	u32 val = 0;
+
+	if (enable) {
+		/* MTCMOS set */
+		if ((cpu == 2) || (cpu == 3))
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCPERPWREN);
+		udelay(100);
+
+		/* Enable core */
+		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN);
+
+		/* unreset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+		/* reset */
+		val |= CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+		/* ISO disable */
+		if ((cpu == 2) || (cpu == 3))
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCISODIS);
+		udelay(1);
+
+		/* WFI Mask */
+		val = readl_relaxed(ctrl_base + SCPERCTRL0);
+		val &= ~(CPU0_WFI_MASK_CFG << cpu);
+		writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+		/* Unreset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+	} else {
+		/* wfi mask */
+		val = readl_relaxed(ctrl_base + SCPERCTRL0);
+		val |= (CPU0_WFI_MASK_CFG << cpu);
+		writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+		/* disable core*/
+		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS);
+
+		if ((cpu == 2) || (cpu == 3)) {
+			/* iso enable */
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCISOEN);
+			udelay(1);
+		}
+
+		/* reset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+		if ((cpu == 2) || (cpu == 3)) {
+			/* MTCMOS unset */
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCPERPWRDIS);
+			udelay(100);
+		}
+	}
+}
+
+static int hi3xxx_hotplug_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+	if (node) {
+		ctrl_base = of_iomap(node, 0);
+		id = HI3620_CTRL;
+		return 0;
+	}
+	id = ERROR_CTRL;
+	return -ENOENT;
+}
+
+void hi3xxx_set_cpu(int cpu, bool enable)
+{
+	if (!ctrl_base) {
+		if (hi3xxx_hotplug_init() < 0)
+			return;
+	}
+
+	if (id == HI3620_CTRL)
+		set_cpu_hi3620(cpu, enable);
+}
+
+static inline void cpu_enter_lowpower(void)
+{
+	unsigned int v;
+
+	flush_cache_all();
+
+	/*
+	 * Turn off coherency and L1 D-cache
+	 */
+	asm volatile(
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, #0x40\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, #0x04\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	  : "=&r" (v)
+	  : "r" (0)
+	  : "cc");
+}
+
+void hi3xxx_cpu_die(unsigned int cpu)
+{
+	cpu_enter_lowpower();
+	hi3xxx_set_cpu_jump(cpu, phys_to_virt(0));
+	cpu_do_idle();
+
+	/* We should have never returned from idle */
+	panic("cpu %d unexpectedly exit from shutdown\n", cpu);
+}
+
+int hi3xxx_cpu_kill(unsigned int cpu)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+	while (hi3xxx_get_cpu_jump(cpu))
+		if (time_after(jiffies, timeout))
+			return 0;
+	hi3xxx_set_cpu(cpu, false);
+	return 1;
+}
diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c
index a4d04c0..4357758 100644
--- a/arch/arm/mach-hi3xxx/platsmp.c
+++ b/arch/arm/mach-hi3xxx/platsmp.c
@@ -73,6 +73,7 @@ static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
 
 static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
+	hi3xxx_set_cpu(cpu, true);
 	hi3xxx_set_cpu_jump(cpu, secondary_startup);
 	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 	return 0;
@@ -81,4 +82,8 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 struct smp_operations hi3xxx_smp_ops __initdata = {
 	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
 	.smp_boot_secondary	= hi3xxx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_die		= hi3xxx_cpu_die,
+	.cpu_kill		= hi3xxx_cpu_kill,
+#endif
 };
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 7/7] ARM: hi3xxx: add hotplug support
@ 2013-10-15  9:16     ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Zhangfei Gao <zhangfei.gao@linaro.org>

Enable hotplug support on hi3xxx platform

How to test:
cat proc/interrupts
echo 0 > /sys/devices/system/cpu/cpuX/online
cat proc/interrupts
echo 1 > /sys/devices/system/cpu/cpuX/online

Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Tested-by: Zhang Mingjun <zhang.mingjun@linaro.org>
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-hi3xxx/Makefile  |   1 +
 arch/arm/mach-hi3xxx/core.h    |   4 +
 arch/arm/mach-hi3xxx/hotplug.c | 200 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-hi3xxx/platsmp.c |   5 ++
 4 files changed, 210 insertions(+)
 create mode 100644 arch/arm/mach-hi3xxx/hotplug.c

diff --git a/arch/arm/mach-hi3xxx/Makefile b/arch/arm/mach-hi3xxx/Makefile
index 7a869a7..c9919e8 100644
--- a/arch/arm/mach-hi3xxx/Makefile
+++ b/arch/arm/mach-hi3xxx/Makefile
@@ -4,3 +4,4 @@
 
 obj-y	+= hi3xxx.o
 obj-$(CONFIG_SMP)		+= platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
diff --git a/arch/arm/mach-hi3xxx/core.h b/arch/arm/mach-hi3xxx/core.h
index 226f020..af23ec2 100644
--- a/arch/arm/mach-hi3xxx/core.h
+++ b/arch/arm/mach-hi3xxx/core.h
@@ -8,4 +8,8 @@ extern int hi3xxx_get_cpu_jump(int cpu);
 extern void secondary_startup(void);
 extern struct smp_operations hi3xxx_smp_ops;
 
+extern void hi3xxx_cpu_die(unsigned int cpu);
+extern int hi3xxx_cpu_kill(unsigned int cpu);
+extern void hi3xxx_set_cpu(int cpu, bool enable);
+
 #endif
diff --git a/arch/arm/mach-hi3xxx/hotplug.c b/arch/arm/mach-hi3xxx/hotplug.c
new file mode 100644
index 0000000..5dc949e
--- /dev/null
+++ b/arch/arm/mach-hi3xxx/hotplug.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013 Linaro Ltd.
+ * Copyright (c) 2013 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "core.h"
+
+/* Sysctrl registers in Hi3620 SoC */
+#define SCISOEN				0xc0
+#define SCISODIS			0xc4
+#define SCPERPWREN			0xd0
+#define SCPERPWRDIS			0xd4
+#define SCCPUCOREEN			0xf4
+#define SCCPUCOREDIS			0xf8
+#define SCPERCTRL0			0x200
+#define SCCPURSTEN			0x410
+#define SCCPURSTDIS			0x414
+
+/*
+ * bit definition in SCISOEN/SCPERPWREN/...
+ *
+ * CPU2_ISO_CTRL	(1 << 5)
+ * CPU3_ISO_CTRL	(1 << 6)
+ * ...
+ */
+#define CPU2_ISO_CTRL			(1 << 5)
+
+/*
+ * bit definition in SCPERCTRL0
+ *
+ * CPU0_WFI_MASK_CFG	(1 << 28)
+ * CPU1_WFI_MASK_CFG	(1 << 29)
+ * ...
+ */
+#define CPU0_WFI_MASK_CFG		(1 << 28)
+
+/*
+ * bit definition in SCCPURSTEN/...
+ *
+ * CPU0_SRST_REQ_EN	(1 << 0)
+ * CPU1_SRST_REQ_EN	(1 << 1)
+ * ...
+ */
+#define CPU0_HPM_SRST_REQ_EN		(1 << 22)
+#define CPU0_DBG_SRST_REQ_EN		(1 << 12)
+#define CPU0_NEON_SRST_REQ_EN		(1 << 4)
+#define CPU0_SRST_REQ_EN		(1 << 0)
+
+enum {
+	HI3620_CTRL,
+	ERROR_CTRL,
+};
+
+static void __iomem *ctrl_base = NULL;
+static int id;
+
+static void set_cpu_hi3620(int cpu, bool enable)
+{
+	u32 val = 0;
+
+	if (enable) {
+		/* MTCMOS set */
+		if ((cpu == 2) || (cpu == 3))
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCPERPWREN);
+		udelay(100);
+
+		/* Enable core */
+		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN);
+
+		/* unreset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+		/* reset */
+		val |= CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+		/* ISO disable */
+		if ((cpu == 2) || (cpu == 3))
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCISODIS);
+		udelay(1);
+
+		/* WFI Mask */
+		val = readl_relaxed(ctrl_base + SCPERCTRL0);
+		val &= ~(CPU0_WFI_MASK_CFG << cpu);
+		writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+		/* Unreset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
+	} else {
+		/* wfi mask */
+		val = readl_relaxed(ctrl_base + SCPERCTRL0);
+		val |= (CPU0_WFI_MASK_CFG << cpu);
+		writel_relaxed(val, ctrl_base + SCPERCTRL0);
+
+		/* disable core*/
+		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS);
+
+		if ((cpu == 2) || (cpu == 3)) {
+			/* iso enable */
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCISOEN);
+			udelay(1);
+		}
+
+		/* reset */
+		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
+			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
+		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);
+
+		if ((cpu == 2) || (cpu == 3)) {
+			/* MTCMOS unset */
+			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
+				       ctrl_base + SCPERPWRDIS);
+			udelay(100);
+		}
+	}
+}
+
+static int hi3xxx_hotplug_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+	if (node) {
+		ctrl_base = of_iomap(node, 0);
+		id = HI3620_CTRL;
+		return 0;
+	}
+	id = ERROR_CTRL;
+	return -ENOENT;
+}
+
+void hi3xxx_set_cpu(int cpu, bool enable)
+{
+	if (!ctrl_base) {
+		if (hi3xxx_hotplug_init() < 0)
+			return;
+	}
+
+	if (id == HI3620_CTRL)
+		set_cpu_hi3620(cpu, enable);
+}
+
+static inline void cpu_enter_lowpower(void)
+{
+	unsigned int v;
+
+	flush_cache_all();
+
+	/*
+	 * Turn off coherency and L1 D-cache
+	 */
+	asm volatile(
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, #0x40\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, #0x04\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	  : "=&r" (v)
+	  : "r" (0)
+	  : "cc");
+}
+
+void hi3xxx_cpu_die(unsigned int cpu)
+{
+	cpu_enter_lowpower();
+	hi3xxx_set_cpu_jump(cpu, phys_to_virt(0));
+	cpu_do_idle();
+
+	/* We should have never returned from idle */
+	panic("cpu %d unexpectedly exit from shutdown\n", cpu);
+}
+
+int hi3xxx_cpu_kill(unsigned int cpu)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+	while (hi3xxx_get_cpu_jump(cpu))
+		if (time_after(jiffies, timeout))
+			return 0;
+	hi3xxx_set_cpu(cpu, false);
+	return 1;
+}
diff --git a/arch/arm/mach-hi3xxx/platsmp.c b/arch/arm/mach-hi3xxx/platsmp.c
index a4d04c0..4357758 100644
--- a/arch/arm/mach-hi3xxx/platsmp.c
+++ b/arch/arm/mach-hi3xxx/platsmp.c
@@ -73,6 +73,7 @@ static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus)
 
 static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
+	hi3xxx_set_cpu(cpu, true);
 	hi3xxx_set_cpu_jump(cpu, secondary_startup);
 	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 	return 0;
@@ -81,4 +82,8 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 struct smp_operations hi3xxx_smp_ops __initdata = {
 	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
 	.smp_boot_secondary	= hi3xxx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_die		= hi3xxx_cpu_die,
+	.cpu_kill		= hi3xxx_cpu_kill,
+#endif
 };
-- 
1.8.1.2

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-15  9:16     ` Haojian Zhuang
@ 2013-10-15 13:00         ` Arnd Bergmann
  -1 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 13:00 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	patches-QSEj5FYQhm4dnm+yROfE0A

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> 
> Add board support with device tree for Hisilicon Hi3620 SoC platform.
> 
> Changelog:
> v10:
> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
> only called if .map_io() isn't assigned. Use .map_io() to setup static
> IO mapping that is used in clock driver.
> 

This seems like a step in the wrong direction. Why would you want to use
a static I/O mapping in the clock driver?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-15 13:00         ` Arnd Bergmann
  0 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> 
> Add board support with device tree for Hisilicon Hi3620 SoC platform.
> 
> Changelog:
> v10:
> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
> only called if .map_io() isn't assigned. Use .map_io() to setup static
> IO mapping that is used in clock driver.
> 

This seems like a step in the wrong direction. Why would you want to use
a static I/O mapping in the clock driver?

	Arnd

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-15 13:00         ` Arnd Bergmann
@ 2013-10-15 13:12             ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15 13:12 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King - ARM Linux, Linus Walleij, Olof Johansson,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, John Stultz, Mike Turquette,
	Grant Likely, Mark Rutland, Kevin Hilman, Stephen Warren,
	Shaojie Sun, devicetree-u79uwXL29TY76Z2rM5mHXA, Patch Tracking

On 15 October 2013 21:00, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>
>> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>>
>> Changelog:
>> v10:
>> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>> only called if .map_io() isn't assigned. Use .map_io() to setup static
>> IO mapping that is used in clock driver.
>>
>
> This seems like a step in the wrong direction. Why would you want to use
> a static I/O mapping in the clock driver?
>
>         Arnd

Because Stephen & Kevin asked me to use unit address in DTS file. They
also require me to use reg property to present real hardware address
in DTS file.

Regards
Haojian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-15 13:12             ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-15 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 15 October 2013 21:00, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>
>> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>>
>> Changelog:
>> v10:
>> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>> only called if .map_io() isn't assigned. Use .map_io() to setup static
>> IO mapping that is used in clock driver.
>>
>
> This seems like a step in the wrong direction. Why would you want to use
> a static I/O mapping in the clock driver?
>
>         Arnd

Because Stephen & Kevin asked me to use unit address in DTS file. They
also require me to use reg property to present real hardware address
in DTS file.

Regards
Haojian

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-15 13:12             ` Haojian Zhuang
@ 2013-10-15 18:06               ` Arnd Bergmann
  -1 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 18:06 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: Mark Rutland, devicetree, Kevin Hilman, Russell King - ARM Linux,
	Shaojie Sun, Stephen Warren, Linus Walleij, Patch Tracking,
	Rob Herring, Grant Likely, John Stultz, Olof Johansson,
	Mike Turquette, tglx, linux-arm-kernel

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> On 15 October 2013 21:00, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
> >>
> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
> >>
> >> Changelog:
> >> v10:
> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
> >> IO mapping that is used in clock driver.
> >>
> >
> > This seems like a step in the wrong direction. Why would you want to use
> > a static I/O mapping in the clock driver?
> >
> 
> Because Stephen & Kevin asked me to use unit address in DTS file. They
> also require me to use reg property to present real hardware address
> in DTS file.

Ah, so it's just an optimization, not required to make the clock driver
work, I misread that. Can you add a comment near the hi3620_io_desc
definition and verify that it still works without it?

I would also recommend to extend that static mapping to the entire
0xfc800000-0xfcbfffff range, or whatever you can use to get the most
I/O devices with a small number of TLB entries.

	Arnd

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-15 18:06               ` Arnd Bergmann
  0 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 18:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> On 15 October 2013 21:00, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
> >>
> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
> >>
> >> Changelog:
> >> v10:
> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
> >> IO mapping that is used in clock driver.
> >>
> >
> > This seems like a step in the wrong direction. Why would you want to use
> > a static I/O mapping in the clock driver?
> >
> 
> Because Stephen & Kevin asked me to use unit address in DTS file. They
> also require me to use reg property to present real hardware address
> in DTS file.

Ah, so it's just an optimization, not required to make the clock driver
work, I misread that. Can you add a comment near the hi3620_io_desc
definition and verify that it still works without it?

I would also recommend to extend that static mapping to the entire
0xfc800000-0xfcbfffff range, or whatever you can use to get the most
I/O devices with a small number of TLB entries.

	Arnd

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

* Re: [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
  2013-10-15  9:16     ` Haojian Zhuang
@ 2013-10-15 18:18         ` Arnd Bergmann
  -1 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 18:18 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	mturquette-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	patches-QSEj5FYQhm4dnm+yROfE0A

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> Enable Hisilicon Hi4511 development platform with device tree support.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Based on my other mail, some more comments here:

> +/ {
> +	clocks {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;

Since all clocks are in the fc802000 page, I would prefer using a non-empty
ranges to map the clocks into their own address space, like

		ranges = <0 0xfc802000 0x1000>;


> +		timer4_mux: timer4_mux@fc802018 {
> +			compatible = "hisilicon,clk-mux";
> +			#clock-cells = <0>;
> +			clocks = <&osc32k &timerclk45>;
> +			clock-output-names = "timer4_mux";
> +			reg = <0xfc802018 0x4>;
> +			clkmux-mask = <0x3>;
> +			clkmux-table = <0 0x1>;
> +		};

which would turn this into 

		timer4_mux: timer4_mux@18 {
			...
			reg = <0x18 0x4>;
			...
		};

The code would not be impacted by this.

On a related note, I find it strange that you have multiple devices with the
same register. Normally, we try to have device node names be generic,
e.g. 'clock@18' rather than 'timer4_mux@18', but that won't work if the
register is the same for all of them. Maybe some DT expert can comment
on this.

> +
> +	amba {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "arm,amba-bus";
> +		interrupt-parent = <&gic>;
> +		ranges;
> +
> +		L2: l2-cache {
> +			compatible = "arm,pl310-cache";
> +			reg = <0xfc10000 0x100000>;
> +			interrupts = <0 15 4>;
> +			cache-unified;
> +			cache-level = <2>;
> +		};

For this node, we could use the same trick with the non-empty ranges, since
all amba devices seem to be in the 0xfc000000 range.

If you do that, it probably makes sense to move the clock controller under here
as well.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
@ 2013-10-15 18:18         ` Arnd Bergmann
  0 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-15 18:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 15 October 2013, Haojian Zhuang wrote:
> Enable Hisilicon Hi4511 development platform with device tree support.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Based on my other mail, some more comments here:

> +/ {
> +	clocks {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;

Since all clocks are in the fc802000 page, I would prefer using a non-empty
ranges to map the clocks into their own address space, like

		ranges = <0 0xfc802000 0x1000>;


> +		timer4_mux: timer4_mux at fc802018 {
> +			compatible = "hisilicon,clk-mux";
> +			#clock-cells = <0>;
> +			clocks = <&osc32k &timerclk45>;
> +			clock-output-names = "timer4_mux";
> +			reg = <0xfc802018 0x4>;
> +			clkmux-mask = <0x3>;
> +			clkmux-table = <0 0x1>;
> +		};

which would turn this into 

		timer4_mux: timer4_mux at 18 {
			...
			reg = <0x18 0x4>;
			...
		};

The code would not be impacted by this.

On a related note, I find it strange that you have multiple devices with the
same register. Normally, we try to have device node names be generic,
e.g. 'clock at 18' rather than 'timer4_mux at 18', but that won't work if the
register is the same for all of them. Maybe some DT expert can comment
on this.

> +
> +	amba {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "arm,amba-bus";
> +		interrupt-parent = <&gic>;
> +		ranges;
> +
> +		L2: l2-cache {
> +			compatible = "arm,pl310-cache";
> +			reg = <0xfc10000 0x100000>;
> +			interrupts = <0 15 4>;
> +			cache-unified;
> +			cache-level = <2>;
> +		};

For this node, we could use the same trick with the non-empty ranges, since
all amba devices seem to be in the 0xfc000000 range.

If you do that, it probably makes sense to move the clock controller under here
as well.

	Arnd

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-15 18:06               ` Arnd Bergmann
@ 2013-10-16  1:08                   ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  1:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King - ARM Linux, Linus Walleij, Olof Johansson,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, John Stultz, Mike Turquette,
	Grant Likely, Mark Rutland, Kevin Hilman, Stephen Warren,
	Shaojie Sun, devicetree-u79uwXL29TY76Z2rM5mHXA, Patch Tracking

On 16 October 2013 02:06, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> On 15 October 2013 21:00, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> >>
>> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>> >>
>> >> Changelog:
>> >> v10:
>> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
>> >> IO mapping that is used in clock driver.
>> >>
>> >
>> > This seems like a step in the wrong direction. Why would you want to use
>> > a static I/O mapping in the clock driver?
>> >
>>
>> Because Stephen & Kevin asked me to use unit address in DTS file. They
>> also require me to use reg property to present real hardware address
>> in DTS file.
>
> Ah, so it's just an optimization, not required to make the clock driver
> work, I misread that. Can you add a comment near the hi3620_io_desc
> definition and verify that it still works without it?
>
Yes, it can work without the IO table. The IO table could save a lot
of virtual address space for IO mapping.

> I would also recommend to extend that static mapping to the entire
> 0xfc800000-0xfcbfffff range, or whatever you can use to get the most
> I/O devices with a small number of TLB entries.
>
>         Arnd

OK. I'll extend the static mapping to the entire range.

Regards
Haojian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-16  1:08                   ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  1:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 October 2013 02:06, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> On 15 October 2013 21:00, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> >>
>> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>> >>
>> >> Changelog:
>> >> v10:
>> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
>> >> IO mapping that is used in clock driver.
>> >>
>> >
>> > This seems like a step in the wrong direction. Why would you want to use
>> > a static I/O mapping in the clock driver?
>> >
>>
>> Because Stephen & Kevin asked me to use unit address in DTS file. They
>> also require me to use reg property to present real hardware address
>> in DTS file.
>
> Ah, so it's just an optimization, not required to make the clock driver
> work, I misread that. Can you add a comment near the hi3620_io_desc
> definition and verify that it still works without it?
>
Yes, it can work without the IO table. The IO table could save a lot
of virtual address space for IO mapping.

> I would also recommend to extend that static mapping to the entire
> 0xfc800000-0xfcbfffff range, or whatever you can use to get the most
> I/O devices with a small number of TLB entries.
>
>         Arnd

OK. I'll extend the static mapping to the entire range.

Regards
Haojian

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-16  1:08                   ` Haojian Zhuang
@ 2013-10-16  1:31                       ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  1:31 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King - ARM Linux, Linus Walleij, Olof Johansson,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, John Stultz, Mike Turquette,
	Grant Likely, Mark Rutland, Kevin Hilman, Stephen Warren,
	Shaojie Sun, devicetree-u79uwXL29TY76Z2rM5mHXA, Patch Tracking

On 16 October 2013 09:08, Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 16 October 2013 02:06, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>> On 15 October 2013 21:00, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>>> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>> >>
>>> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>>> >>
>>> >> Changelog:
>>> >> v10:
>>> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>>> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
>>> >> IO mapping that is used in clock driver.
>>> >>
>>> >
>>> > This seems like a step in the wrong direction. Why would you want to use
>>> > a static I/O mapping in the clock driver?
>>> >
>>>
>>> Because Stephen & Kevin asked me to use unit address in DTS file. They
>>> also require me to use reg property to present real hardware address
>>> in DTS file.
>>
>> Ah, so it's just an optimization, not required to make the clock driver
>> work, I misread that. Can you add a comment near the hi3620_io_desc
>> definition and verify that it still works without it?
>>
> Yes, it can work without the IO table. The IO table could save a lot
> of virtual address space for IO mapping.
>
>> I would also recommend to extend that static mapping to the entire
>> 0xfc800000-0xfcbfffff range, or whatever you can use to get the most
>> I/O devices with a small number of TLB entries.
>>
>>         Arnd
>
> OK. I'll extend the static mapping to the entire range.
>
> Regards
> Haojian

Oh, no. I shouldn't extend the static mapping table to the entire range.

Most of the registers only need to map once in the probe() function
of the driver. Whether it's using static mapping or dynamic mapping,
there's no difference.

 The sysctrl register bank is used in both clock & platform
driver. Each clock node contains reg property, it needs to be parsed
by of_iomap(). Hotplug & SMP platform driver needs to parse sysctrl
register bank also. If I don't choose the static IO mapping for sysctrl
register bank, I have to define some global variable to store the
virtual address mapping. Or I have to cost lots of redundant virtual
address space for the same IO mapping.

So I'll only keep the static IO mapping for sysctrl.

Regards
Haojian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-16  1:31                       ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  1:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 October 2013 09:08, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
> On 16 October 2013 02:06, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>> On 15 October 2013 21:00, Arnd Bergmann <arnd@arndb.de> wrote:
>>> > On Tuesday 15 October 2013, Haojian Zhuang wrote:
>>> >>
>>> >> Add board support with device tree for Hisilicon Hi3620 SoC platform.
>>> >>
>>> >> Changelog:
>>> >> v10:
>>> >> 1. Add .map_io() & debug_ll_io_init() back. Since debug_ll_io_init() is
>>> >> only called if .map_io() isn't assigned. Use .map_io() to setup static
>>> >> IO mapping that is used in clock driver.
>>> >>
>>> >
>>> > This seems like a step in the wrong direction. Why would you want to use
>>> > a static I/O mapping in the clock driver?
>>> >
>>>
>>> Because Stephen & Kevin asked me to use unit address in DTS file. They
>>> also require me to use reg property to present real hardware address
>>> in DTS file.
>>
>> Ah, so it's just an optimization, not required to make the clock driver
>> work, I misread that. Can you add a comment near the hi3620_io_desc
>> definition and verify that it still works without it?
>>
> Yes, it can work without the IO table. The IO table could save a lot
> of virtual address space for IO mapping.
>
>> I would also recommend to extend that static mapping to the entire
>> 0xfc800000-0xfcbfffff range, or whatever you can use to get the most
>> I/O devices with a small number of TLB entries.
>>
>>         Arnd
>
> OK. I'll extend the static mapping to the entire range.
>
> Regards
> Haojian

Oh, no. I shouldn't extend the static mapping table to the entire range.

Most of the registers only need to map once in the probe() function
of the driver. Whether it's using static mapping or dynamic mapping,
there's no difference.

 The sysctrl register bank is used in both clock & platform
driver. Each clock node contains reg property, it needs to be parsed
by of_iomap(). Hotplug & SMP platform driver needs to parse sysctrl
register bank also. If I don't choose the static IO mapping for sysctrl
register bank, I have to define some global variable to store the
virtual address mapping. Or I have to cost lots of redundant virtual
address space for the same IO mapping.

So I'll only keep the static IO mapping for sysctrl.

Regards
Haojian

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

* Re: [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
  2013-10-15 18:18         ` Arnd Bergmann
@ 2013-10-16  2:09             ` Haojian Zhuang
  -1 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  2:09 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King - ARM Linux, Linus Walleij, Olof Johansson,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, John Stultz, Mike Turquette,
	Grant Likely, Mark Rutland, Kevin Hilman, Stephen Warren,
	Shaojie Sun, devicetree-u79uwXL29TY76Z2rM5mHXA, Patch Tracking

On 16 October 2013 02:18, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> Enable Hisilicon Hi4511 development platform with device tree support.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> Based on my other mail, some more comments here:
>
>> +/ {
>> +     clocks {
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             ranges;
>
> Since all clocks are in the fc802000 page, I would prefer using a non-empty
> ranges to map the clocks into their own address space, like
>
>                 ranges = <0 0xfc802000 0x1000>;
>
>
OK.

>> +             timer4_mux: timer4_mux@fc802018 {
>> +                     compatible = "hisilicon,clk-mux";
>> +                     #clock-cells = <0>;
>> +                     clocks = <&osc32k &timerclk45>;
>> +                     clock-output-names = "timer4_mux";
>> +                     reg = <0xfc802018 0x4>;
>> +                     clkmux-mask = <0x3>;
>> +                     clkmux-table = <0 0x1>;
>> +             };
>
> which would turn this into
>
>                 timer4_mux: timer4_mux@18 {
>                         ...
>                         reg = <0x18 0x4>;
>                         ...
>                 };
>
> The code would not be impacted by this.
>
> On a related note, I find it strange that you have multiple devices with the
> same register. Normally, we try to have device node names be generic,
> e.g. 'clock@18' rather than 'timer4_mux@18', but that won't work if the
> register is the same for all of them. Maybe some DT expert can comment
> on this.
>
Because multiple clock nodes (clock mux/clock gate/clock divider) are
sharing the same register. I think that it's common on ARM SoC. At
least, I can find this in both Hisilicon & Marvell PXA/MMP SoC.

If I force to merge multiple clock nodes into the same device node,
it'll become mess. Different clock nodes have different properties.
The property won't work any more if they are merged into the same
device node.

>> +
>> +     amba {
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             compatible = "arm,amba-bus";
>> +             interrupt-parent = <&gic>;
>> +             ranges;
>> +
>> +             L2: l2-cache {
>> +                     compatible = "arm,pl310-cache";
>> +                     reg = <0xfc10000 0x100000>;
>> +                     interrupts = <0 15 4>;
>> +                     cache-unified;
>> +                     cache-level = <2>;
>> +             };
>
> For this node, we could use the same trick with the non-empty ranges, since
> all amba devices seem to be in the 0xfc000000 range.
>
OK.

> If you do that, it probably makes sense to move the clock controller under here
> as well.
Could I keep them into hi3620-clk.dtsi? Since both hi3620.dtsi &
hi3620-clk.dtsi are not small, merge them together only make people
reading hard.

>
>         Arnd

Best Regards
Haojian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
@ 2013-10-16  2:09             ` Haojian Zhuang
  0 siblings, 0 replies; 38+ messages in thread
From: Haojian Zhuang @ 2013-10-16  2:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 October 2013 02:18, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:
>> Enable Hisilicon Hi4511 development platform with device tree support.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> Based on my other mail, some more comments here:
>
>> +/ {
>> +     clocks {
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             ranges;
>
> Since all clocks are in the fc802000 page, I would prefer using a non-empty
> ranges to map the clocks into their own address space, like
>
>                 ranges = <0 0xfc802000 0x1000>;
>
>
OK.

>> +             timer4_mux: timer4_mux at fc802018 {
>> +                     compatible = "hisilicon,clk-mux";
>> +                     #clock-cells = <0>;
>> +                     clocks = <&osc32k &timerclk45>;
>> +                     clock-output-names = "timer4_mux";
>> +                     reg = <0xfc802018 0x4>;
>> +                     clkmux-mask = <0x3>;
>> +                     clkmux-table = <0 0x1>;
>> +             };
>
> which would turn this into
>
>                 timer4_mux: timer4_mux at 18 {
>                         ...
>                         reg = <0x18 0x4>;
>                         ...
>                 };
>
> The code would not be impacted by this.
>
> On a related note, I find it strange that you have multiple devices with the
> same register. Normally, we try to have device node names be generic,
> e.g. 'clock at 18' rather than 'timer4_mux at 18', but that won't work if the
> register is the same for all of them. Maybe some DT expert can comment
> on this.
>
Because multiple clock nodes (clock mux/clock gate/clock divider) are
sharing the same register. I think that it's common on ARM SoC. At
least, I can find this in both Hisilicon & Marvell PXA/MMP SoC.

If I force to merge multiple clock nodes into the same device node,
it'll become mess. Different clock nodes have different properties.
The property won't work any more if they are merged into the same
device node.

>> +
>> +     amba {
>> +             #address-cells = <1>;
>> +             #size-cells = <1>;
>> +             compatible = "arm,amba-bus";
>> +             interrupt-parent = <&gic>;
>> +             ranges;
>> +
>> +             L2: l2-cache {
>> +                     compatible = "arm,pl310-cache";
>> +                     reg = <0xfc10000 0x100000>;
>> +                     interrupts = <0 15 4>;
>> +                     cache-unified;
>> +                     cache-level = <2>;
>> +             };
>
> For this node, we could use the same trick with the non-empty ranges, since
> all amba devices seem to be in the 0xfc000000 range.
>
OK.

> If you do that, it probably makes sense to move the clock controller under here
> as well.
Could I keep them into hi3620-clk.dtsi? Since both hi3620.dtsi &
hi3620-clk.dtsi are not small, merge them together only make people
reading hard.

>
>         Arnd

Best Regards
Haojian

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

* Re: [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
  2013-10-16  2:09             ` Haojian Zhuang
@ 2013-10-16  7:10               ` Arnd Bergmann
  -1 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-16  7:10 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: Mark Rutland, devicetree, Kevin Hilman, Russell King - ARM Linux,
	Shaojie Sun, Stephen Warren, Linus Walleij, Patch Tracking,
	Rob Herring, Grant Likely, John Stultz, Olof Johansson,
	Mike Turquette, tglx, linux-arm-kernel

On Wednesday 16 October 2013, Haojian Zhuang wrote:
> > If you do that, it probably makes sense to move the clock controller under here
> > as well.
> Could I keep them into hi3620-clk.dtsi? Since both hi3620.dtsi &
> hi3620-clk.dtsi are not small, merge them together only make people
> reading hard.

Yes, of course. The location in the tree is independent of what file they
are in. I was just suggesting to have the "clocks" node under "amba".

	Arnd

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
@ 2013-10-16  7:10               ` Arnd Bergmann
  0 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-16  7:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 October 2013, Haojian Zhuang wrote:
> > If you do that, it probably makes sense to move the clock controller under here
> > as well.
> Could I keep them into hi3620-clk.dtsi? Since both hi3620.dtsi &
> hi3620-clk.dtsi are not small, merge them together only make people
> reading hard.

Yes, of course. The location in the tree is independent of what file they
are in. I was just suggesting to have the "clocks" node under "amba".

	Arnd

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

* Re: [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
  2013-10-15 18:18         ` Arnd Bergmann
@ 2013-10-16  7:26             ` Linus Walleij
  -1 siblings, 0 replies; 38+ messages in thread
From: Linus Walleij @ 2013-10-16  7:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Haojian Zhuang, Russell King - ARM Linux, Olof Johansson,
	Rob Herring, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Thomas Gleixner, John Stultz, Mike Turquette, Grant Likely,
	Mark Rutland, Kevin Hilman, Stephen Warren, Shaojie Sun,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Patch Tracking

On Tue, Oct 15, 2013 at 8:18 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:

> Since all clocks are in the fc802000 page, I would prefer using a non-empty
> ranges to map the clocks into their own address space, like
>
>                 ranges = <0 0xfc802000 0x1000>;
>
>
>> +             timer4_mux: timer4_mux@fc802018 {
>> +                     compatible = "hisilicon,clk-mux";
>> +                     #clock-cells = <0>;
>> +                     clocks = <&osc32k &timerclk45>;
>> +                     clock-output-names = "timer4_mux";
>> +                     reg = <0xfc802018 0x4>;
>> +                     clkmux-mask = <0x3>;
>> +                     clkmux-table = <0 0x1>;
>> +             };
>
> which would turn this into
>
>                 timer4_mux: timer4_mux@18 {
>                         ...
>                         reg = <0x18 0x4>;
>                         ...
>                 };
>
> The code would not be impacted by this.

I'd rather question the addition of a reg =<>; specifier
for each and every clock.

Knowing the offsets of each and every register in a
memory-mapped device is usually overdesign, and
goes from specifying register base to specifying
register offsets and to me that is overspecifying.

I'd rather give each clock a unique ID or something,
then let the driver know the offsets, and specify the
base and size in the top node.

This becomes more obvious with a second silicon
revision moving the registers around - with this
design all of the clocks need updating, but if you're
lucky with less knowledge in the DTS you only need
a new compatible string and the knowledge of the new
whereabout for the regs is kept in the driver.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 3/7] ARM: dts: enable hi4511 with device tree
@ 2013-10-16  7:26             ` Linus Walleij
  0 siblings, 0 replies; 38+ messages in thread
From: Linus Walleij @ 2013-10-16  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 15, 2013 at 8:18 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 15 October 2013, Haojian Zhuang wrote:

> Since all clocks are in the fc802000 page, I would prefer using a non-empty
> ranges to map the clocks into their own address space, like
>
>                 ranges = <0 0xfc802000 0x1000>;
>
>
>> +             timer4_mux: timer4_mux at fc802018 {
>> +                     compatible = "hisilicon,clk-mux";
>> +                     #clock-cells = <0>;
>> +                     clocks = <&osc32k &timerclk45>;
>> +                     clock-output-names = "timer4_mux";
>> +                     reg = <0xfc802018 0x4>;
>> +                     clkmux-mask = <0x3>;
>> +                     clkmux-table = <0 0x1>;
>> +             };
>
> which would turn this into
>
>                 timer4_mux: timer4_mux at 18 {
>                         ...
>                         reg = <0x18 0x4>;
>                         ...
>                 };
>
> The code would not be impacted by this.

I'd rather question the addition of a reg =<>; specifier
for each and every clock.

Knowing the offsets of each and every register in a
memory-mapped device is usually overdesign, and
goes from specifying register base to specifying
register offsets and to me that is overspecifying.

I'd rather give each clock a unique ID or something,
then let the driver know the offsets, and specify the
base and size in the top node.

This becomes more obvious with a second silicon
revision moving the registers around - with this
design all of the clocks need updating, but if you're
lucky with less knowledge in the DTS you only need
a new compatible string and the knowledge of the new
whereabout for the regs is kept in the driver.

Yours,
Linus Walleij

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

* Re: [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
  2013-10-16  1:31                       ` Haojian Zhuang
@ 2013-10-16  7:27                         ` Arnd Bergmann
  -1 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-16  7:27 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: Mark Rutland, devicetree, Kevin Hilman, Russell King - ARM Linux,
	Shaojie Sun, Stephen Warren, Linus Walleij, Patch Tracking,
	Rob Herring, Grant Likely, John Stultz, Olof Johansson,
	Mike Turquette, tglx, linux-arm-kernel

On Wednesday 16 October 2013, Haojian Zhuang wrote:
> Oh, no. I shouldn't extend the static mapping table to the entire range.
> 
> Most of the registers only need to map once in the probe() function
> of the driver. Whether it's using static mapping or dynamic mapping,
> there's no difference.

There is a small difference in that having a megabyte-sized mapping will
reduce the number of TLB entries required for I/O access, which can
improve performance slightly. Other platforms do it for this reason.

>  The sysctrl register bank is used in both clock & platform
> driver. Each clock node contains reg property, it needs to be parsed
> by of_iomap(). Hotplug & SMP platform driver needs to parse sysctrl
> register bank also. If I don't choose the static IO mapping for sysctrl
> register bank, I have to define some global variable to store the
> virtual address mapping. Or I have to cost lots of redundant virtual
> address space for the same IO mapping.

It's a small cost, but your approach makes sense, just make sure
you have a comment in the map_io code explaining it.

> So I'll only keep the static IO mapping for sysctrl.

I'd still choose the larger mapping, but I'll leave the decision to you.

	Arnd

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

* [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree
@ 2013-10-16  7:27                         ` Arnd Bergmann
  0 siblings, 0 replies; 38+ messages in thread
From: Arnd Bergmann @ 2013-10-16  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 October 2013, Haojian Zhuang wrote:
> Oh, no. I shouldn't extend the static mapping table to the entire range.
> 
> Most of the registers only need to map once in the probe() function
> of the driver. Whether it's using static mapping or dynamic mapping,
> there's no difference.

There is a small difference in that having a megabyte-sized mapping will
reduce the number of TLB entries required for I/O access, which can
improve performance slightly. Other platforms do it for this reason.

>  The sysctrl register bank is used in both clock & platform
> driver. Each clock node contains reg property, it needs to be parsed
> by of_iomap(). Hotplug & SMP platform driver needs to parse sysctrl
> register bank also. If I don't choose the static IO mapping for sysctrl
> register bank, I have to define some global variable to store the
> virtual address mapping. Or I have to cost lots of redundant virtual
> address space for the same IO mapping.

It's a small cost, but your approach makes sense, just make sure
you have a comment in the map_io code explaining it.

> So I'll only keep the static IO mapping for sysctrl.

I'd still choose the larger mapping, but I'll leave the decision to you.

	Arnd

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

* Re: [PATCH v10 1/7] clk: hi3xxx: add clock support
  2013-10-15  9:16     ` Haojian Zhuang
@ 2013-10-30 19:44         ` Mike Turquette
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Turquette @ 2013-10-30 19:44 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	olof-nZhT3qVonbNeoWH0uzbU5w, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	tglx-hfZtesqFncYOwBW4kG4KsQ, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	khilman-QSEj5FYQhm4dnm+yROfE0A, swarren-3lzwWm7+Weoh9ZMKESR00Q,
	shaojie.sun-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, Haojian Zhuang

Quoting Haojian Zhuang (2013-10-15 02:16:11)
> Add clock support with device tree on Hisilicon SoC.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Mike Turquette <mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Hello Haojian,

This patch looks mostly good to me but I have a few comments on the
binding below.

> ---
>  .../devicetree/bindings/clock/hisilicon.txt        |  99 +++++++++
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/hisilicon/Makefile                     |   2 +
>  drivers/clk/hisilicon/clk-hi3xxx.c                 | 221 +++++++++++++++++++++
>  drivers/clk/hisilicon/clk-hi3xxx.h                 |  34 ++++
>  drivers/clk/hisilicon/clkgate-seperated.c          | 129 ++++++++++++
>  6 files changed, 486 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
>  create mode 100644 drivers/clk/hisilicon/Makefile
>  create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.c
>  create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.h
>  create mode 100644 drivers/clk/hisilicon/clkgate-seperated.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
> new file mode 100644
> index 0000000..c29b9ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
> @@ -0,0 +1,99 @@
> +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,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.
> + - reg : the mux register address. It should be the offset of the container.
> + - clkmux-mask : mask bits of the mux register.
> + - clkmux-table : array of mux select bits.
> +
> +Optional properties for mux clocks:
> + - clkmux-hiword-mask : indicates that the bit[31:16] are the hiword mask
> +       of mux selected bits (bit[15:0]). The bit[15:0] is valid only when
> +       bit[31:16] is set.

The masks are enumerated in clkmux-table. Can these masks include the
hiword-mask bits as well? This will mean that you can eliminate the
clkmux-hiword-mask property entirely. As an example:


	reg = <0xfc802000 0x4>;
	clkmux-table = <0x80000000 0x80008000>;

> +
> +
> +
> +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.
> + - reg : the mux register address. It should be the offset of the container.
> + - clkgate : bit index to control the clock gate in the gate register.
> +
> +Optional properties for gate clocks:
> + - clkgate-inverted : it indicates that setting 0 could enable the clock gate
> +       and setting 1 could disable the clock gate.
> + - clkgate-seperated-reg : it indicates that there're three continuous
> +       registers (enable, disable & status) for the same clock gate.
> +
> +
> +
> +Required properties for divider clocks:
> + - compatible : shall be "hisilicon,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.
> + - reg : the divider register address. It should be the offset of the
> +       container.
> + - clkdiv-mask : mask bits of the divider register.
> + - clkdiv-min : the minimum divider of the clock divider.
> + - clkdiv-max : the maximum divider of the clock divider.
> +
> +Optional properties for divider clocks:
> + - clkdiv-hiword-mask : indicates that the bit[31:16] are the hiword mask
> +       of divider selected bits (bit[15:0]). The bit[15:0] is valid only when
> +       bit[31:16] is set.
> +
> +
> +
> +For example:
> +               timer0_mux: timer0_mux@fc802000 {
> +                       compatible = "hisilicon,clk-mux";
> +                       #clock-cells = <0>;
> +                       clocks = <&osc32k &timerclk01>;
> +                       clock-output-names = "timer0_mux";
> +                       reg = <0xfc802000 0x4>;
> +                       clkmux-mask = <0x8000>;
> +                       clkmux-table = <0 0x8000>;

Can you eliminate the clkmux-mask property as well? Since you enumerate
the clkmux-table property you should be able to derive the mask from the
entries in that table.

Regards,
Mike
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v10 1/7] clk: hi3xxx: add clock support
@ 2013-10-30 19:44         ` Mike Turquette
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Turquette @ 2013-10-30 19:44 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Haojian Zhuang (2013-10-15 02:16:11)
> Add clock support with device tree on Hisilicon SoC.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> Cc: Mike Turquette <mturquette@linaro.org>

Hello Haojian,

This patch looks mostly good to me but I have a few comments on the
binding below.

> ---
>  .../devicetree/bindings/clock/hisilicon.txt        |  99 +++++++++
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/hisilicon/Makefile                     |   2 +
>  drivers/clk/hisilicon/clk-hi3xxx.c                 | 221 +++++++++++++++++++++
>  drivers/clk/hisilicon/clk-hi3xxx.h                 |  34 ++++
>  drivers/clk/hisilicon/clkgate-seperated.c          | 129 ++++++++++++
>  6 files changed, 486 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt
>  create mode 100644 drivers/clk/hisilicon/Makefile
>  create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.c
>  create mode 100644 drivers/clk/hisilicon/clk-hi3xxx.h
>  create mode 100644 drivers/clk/hisilicon/clkgate-seperated.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
> new file mode 100644
> index 0000000..c29b9ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
> @@ -0,0 +1,99 @@
> +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,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.
> + - reg : the mux register address. It should be the offset of the container.
> + - clkmux-mask : mask bits of the mux register.
> + - clkmux-table : array of mux select bits.
> +
> +Optional properties for mux clocks:
> + - clkmux-hiword-mask : indicates that the bit[31:16] are the hiword mask
> +       of mux selected bits (bit[15:0]). The bit[15:0] is valid only when
> +       bit[31:16] is set.

The masks are enumerated in clkmux-table. Can these masks include the
hiword-mask bits as well? This will mean that you can eliminate the
clkmux-hiword-mask property entirely. As an example:


	reg = <0xfc802000 0x4>;
	clkmux-table = <0x80000000 0x80008000>;

> +
> +
> +
> +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.
> + - reg : the mux register address. It should be the offset of the container.
> + - clkgate : bit index to control the clock gate in the gate register.
> +
> +Optional properties for gate clocks:
> + - clkgate-inverted : it indicates that setting 0 could enable the clock gate
> +       and setting 1 could disable the clock gate.
> + - clkgate-seperated-reg : it indicates that there're three continuous
> +       registers (enable, disable & status) for the same clock gate.
> +
> +
> +
> +Required properties for divider clocks:
> + - compatible : shall be "hisilicon,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.
> + - reg : the divider register address. It should be the offset of the
> +       container.
> + - clkdiv-mask : mask bits of the divider register.
> + - clkdiv-min : the minimum divider of the clock divider.
> + - clkdiv-max : the maximum divider of the clock divider.
> +
> +Optional properties for divider clocks:
> + - clkdiv-hiword-mask : indicates that the bit[31:16] are the hiword mask
> +       of divider selected bits (bit[15:0]). The bit[15:0] is valid only when
> +       bit[31:16] is set.
> +
> +
> +
> +For example:
> +               timer0_mux: timer0_mux at fc802000 {
> +                       compatible = "hisilicon,clk-mux";
> +                       #clock-cells = <0>;
> +                       clocks = <&osc32k &timerclk01>;
> +                       clock-output-names = "timer0_mux";
> +                       reg = <0xfc802000 0x4>;
> +                       clkmux-mask = <0x8000>;
> +                       clkmux-table = <0 0x8000>;

Can you eliminate the clkmux-mask property as well? Since you enumerate
the clkmux-table property you should be able to derive the mask from the
entries in that table.

Regards,
Mike

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

end of thread, other threads:[~2013-10-30 19:44 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-15  9:16 [PATCH v10 0/7] enable hi3xxx SoC Haojian Zhuang
2013-10-15  9:16 ` Haojian Zhuang
     [not found] ` <1381828577-27998-1-git-send-email-haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-10-15  9:16   ` [PATCH v10 1/7] clk: hi3xxx: add clock support Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
     [not found]     ` <1381828577-27998-2-git-send-email-haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-10-30 19:44       ` Mike Turquette
2013-10-30 19:44         ` Mike Turquette
2013-10-15  9:16   ` [PATCH v10 2/7] ARM: hi3xxx: add board support with device tree Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
     [not found]     ` <1381828577-27998-3-git-send-email-haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-10-15 13:00       ` Arnd Bergmann
2013-10-15 13:00         ` Arnd Bergmann
     [not found]         ` <201310151500.36959.arnd-r2nGTMty4D4@public.gmane.org>
2013-10-15 13:12           ` Haojian Zhuang
2013-10-15 13:12             ` Haojian Zhuang
2013-10-15 18:06             ` Arnd Bergmann
2013-10-15 18:06               ` Arnd Bergmann
     [not found]               ` <201310152006.38824.arnd-r2nGTMty4D4@public.gmane.org>
2013-10-16  1:08                 ` Haojian Zhuang
2013-10-16  1:08                   ` Haojian Zhuang
     [not found]                   ` <CAD6h2NRvCdfNef_q=6JyNvv2ZsObmwmh=wgcKu=j6RokE3-sFg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-10-16  1:31                     ` Haojian Zhuang
2013-10-16  1:31                       ` Haojian Zhuang
2013-10-16  7:27                       ` Arnd Bergmann
2013-10-16  7:27                         ` Arnd Bergmann
2013-10-15  9:16   ` [PATCH v10 3/7] ARM: dts: enable hi4511 " Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
     [not found]     ` <1381828577-27998-4-git-send-email-haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-10-15 18:18       ` Arnd Bergmann
2013-10-15 18:18         ` Arnd Bergmann
     [not found]         ` <201310152018.10908.arnd-r2nGTMty4D4@public.gmane.org>
2013-10-16  2:09           ` Haojian Zhuang
2013-10-16  2:09             ` Haojian Zhuang
2013-10-16  7:10             ` Arnd Bergmann
2013-10-16  7:10               ` Arnd Bergmann
2013-10-16  7:26           ` Linus Walleij
2013-10-16  7:26             ` Linus Walleij
2013-10-15  9:16   ` [PATCH v10 4/7] ARM: config: enable hi3xxx in multi_v7_defconfig Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
2013-10-15  9:16   ` [PATCH v10 5/7] ARM: config: add defconfig for Hi3xxx Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
2013-10-15  9:16   ` [PATCH v10 6/7] ARM: hi3xxx: add smp support Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang
2013-10-15  9:16   ` [PATCH v10 7/7] ARM: hi3xxx: add hotplug support Haojian Zhuang
2013-10-15  9:16     ` Haojian Zhuang

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.