linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc
@ 2013-02-28  7:19 Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 2/7] clk: hs: add clock support Haojian Zhuang
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Support UART0 debug ll on hisilicon Hi3620 SoC.

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

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index acdddda..32958a6 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -240,6 +240,20 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX6Q.
 
+	config DEBUG_HI3620_UART
+		bool "Hisilicon HI3620 Debug UART"
+		depends on ARCH_HS
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on HI3620 UART.
+
+	config DEBUG_HI3716_UART
+		bool "Hisilicon Hi3716 Debug UART"
+		depends on ARCH_HS
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on HI3716 UART.
+
 	config DEBUG_MMP_UART2
 		bool "Kernel low-level debugging message via MMP UART2"
 		depends on ARCH_MMP
@@ -589,6 +603,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_IMX53_UART ||\
 				 DEBUG_IMX6Q_UART
 	default "debug/highbank.S" if DEBUG_HIGHBANK_UART
+	default "debug/hisilicon.S" if DEBUG_HI3620_UART || DEBUG_HI3716_UART
 	default "debug/mvebu.S" if DEBUG_MVEBU_UART
 	default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
 	default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART
diff --git a/arch/arm/include/debug/hisilicon.S b/arch/arm/include/debug/hisilicon.S
new file mode 100644
index 0000000..e719545
--- /dev/null
+++ b/arch/arm/include/debug/hisilicon.S
@@ -0,0 +1,30 @@
+/*
+ * Early serial output macro for Hisilicon SoC
+ *
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ *
+ * Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_DEBUG_HI3620_UART)
+#define HS_UART_PHYS_BASE	0xfcb00000
+#define HS_UART_VIRT_BASE	0xfeb00000
+#elif defined(CONFIG_DEBUG_HI3716_UART)
+#define HS_UART_PHYS_BASE	0xf8b00000
+#define HS_UART_VIRT_BASE	0xfeb00000
+#endif
+
+#if defined(CONFIG_DEBUG_HI3620_UART) || defined(CONFIG_DEBUG_HI3716_UART)
+		.macro	addruart,rp,rv,tmp
+		ldr	\rp, =HS_UART_PHYS_BASE
+		ldr	\rv, =HS_UART_VIRT_BASE
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
+
+#endif
-- 
1.7.10.4

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

* [PATCH 2/7] clk: hs: add clock support
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  2013-02-28 12:48   ` Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 3/7] ARM: hs: add board support with device tree Haojian Zhuang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 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>
---
 drivers/clk/Makefile |    1 +
 drivers/clk/clk-hs.c |  463 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 464 insertions(+)
 create mode 100644 drivers/clk/clk-hs.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 300d477..2d3a08d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK)	+= clk-mux.o
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835.o
 obj-$(CONFIG_ARCH_NOMADIK)	+= clk-nomadik.o
 obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
+obj-$(CONFIG_ARCH_HS)		+= clk-hs.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs/
 obj-$(CONFIG_ARCH_SOCFPGA)	+= socfpga/
 obj-$(CONFIG_PLAT_SPEAR)	+= spear/
diff --git a/drivers/clk/clk-hs.c b/drivers/clk/clk-hs.c
new file mode 100644
index 0000000..e802bf4
--- /dev/null
+++ b/drivers/clk/clk-hs.c
@@ -0,0 +1,463 @@
+/*
+ * Hisilicon clock driver
+ *
+ * Copyright (c) 2012-2013 Hisilicon Limited.
+ * Copyright (c) 2012-2013 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *	   Xin Li <li.xin@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#define HI3620_DISABLE_OFF		0x4
+#define HI3620_STATUS_OFF		0x8
+
+struct hi3620_periclk {
+	struct clk_hw	hw;
+	void __iomem	*enable;	/* enable register */
+	void __iomem	*reset;		/* reset register */
+	u32		ebits;		/* bits in enable/disable register */
+	u32		rbits;		/* bits in reset/unreset register */
+	spinlock_t	*lock;
+};
+
+struct hi3620_muxclk {
+	struct clk_hw	hw;
+	void __iomem	*reg;		/* mux register */
+	u8		shift;
+	u8		width;
+	u32		ebits;		/* enable bits in mux register */
+	u32		mbits;		/* mask bits in mux register */
+	spinlock_t	*lock;
+};
+
+struct hs_clk {
+	void __iomem	*pmctrl;
+	void __iomem	*sctrl;
+	spinlock_t	lock;
+};
+
+static struct hs_clk hs_clk;
+
+static int hi3620_clkgate_prepare(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
+	writel_relaxed(pclk->rbits, pclk->reset + HI3620_DISABLE_OFF);
+	readl_relaxed(pclk->reset + HI3620_STATUS_OFF);
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+	return 0;
+}
+
+static int hi3620_clkgate_enable(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	writel_relaxed(pclk->ebits, pclk->enable);
+	readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+	return 0;
+}
+
+static void hi3620_clkgate_disable(struct clk_hw *hw)
+{
+	struct hi3620_periclk *pclk;
+	unsigned long flags = 0;
+
+	pclk = container_of(hw, struct hi3620_periclk, hw);
+	if (pclk->lock)
+		spin_lock_irqsave(pclk->lock, flags);
+	writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
+	readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
+	if (pclk->lock)
+		spin_unlock_irqrestore(pclk->lock, flags);
+}
+
+static struct clk_ops hi3620_clkgate_ops = {
+	.prepare	= hi3620_clkgate_prepare,
+	.enable		= hi3620_clkgate_enable,
+	.disable	= hi3620_clkgate_disable,
+};
+
+static void __init hi3620_clkgate_setup(struct device_node *np)
+{
+	struct hi3620_periclk *pclk;
+	struct clk_init_data *init;
+	struct clk *clk;
+	const char *clk_name, *name, **parent_names;
+	u32 rdata[2], gdata[2];
+
+	if (!hs_clk.sctrl)
+		return;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,hi3620-clkreset",
+				       &rdata[0], 2))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,hi3620-clkgate",
+				       &gdata[0], 2))
+		return;
+	if (rdata[1] >= 32 || gdata[1] >= 32)
+		return;
+
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		return;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	pclk = kzalloc(sizeof(*pclk), GFP_KERNEL);
+	if (!pclk)
+		goto err;
+
+	init = kzalloc(sizeof(*init), GFP_KERNEL);
+	if (!init)
+		goto err_pclk;
+	init->name = kstrdup(clk_name, GFP_KERNEL);
+	init->ops = &hi3620_clkgate_ops;
+	init->flags = CLK_SET_RATE_PARENT;
+	init->parent_names = parent_names;
+	init->num_parents = 1;
+
+	pclk->reset = hs_clk.sctrl + rdata[0];
+	pclk->rbits = 1 << rdata[1];
+	pclk->enable = hs_clk.sctrl + gdata[0];
+	pclk->ebits = 1 << gdata[1];
+	pclk->lock = &hs_clk.lock;
+	pclk->hw.init = init;
+
+	clk = clk_register(NULL, &pclk->hw);
+	if (IS_ERR(clk))
+		goto err_init;
+	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_init:
+	kfree(init);
+err_pclk:
+	kfree(pclk);
+err:
+	kfree(parent_names);
+}
+
+static u8 hi3620_clk_get_parent(struct clk_hw *hw)
+{
+	struct hi3620_muxclk *mclk;
+	u32 data;
+	unsigned long flags = 0;
+
+	mclk = container_of(hw, struct hi3620_muxclk, hw);
+
+	if (mclk->lock)
+		spin_lock_irqsave(mclk->lock, flags);
+
+	data = readl_relaxed(mclk->reg) >> mclk->shift;
+	data &= (1 << mclk->width) - 1;
+
+	if (mclk->lock)
+		spin_unlock_irqrestore(mclk->lock, flags);
+
+	if (data >= __clk_get_num_parents(hw->clk))
+		return -EINVAL;
+
+	return (u8)data;
+}
+
+static int hi3620_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct hi3620_muxclk *mclk;
+	u32 data;
+	unsigned long flags = 0;
+
+	mclk = container_of(hw, struct hi3620_muxclk, hw);
+
+	if (mclk->lock)
+		spin_lock_irqsave(mclk->lock, flags);
+
+	data = readl_relaxed(mclk->reg);
+	data &= ~(((1 << mclk->width) - 1) << mclk->shift);
+	data |= index << mclk->shift;
+	writel_relaxed(data, mclk->reg);
+	/* set mask enable bits */
+	data |= mclk->mbits;
+	writel_relaxed(data, mclk->reg);
+
+	if (mclk->lock)
+		spin_unlock_irqrestore(mclk->lock, flags);
+
+	return 0;
+}
+
+static struct clk_ops hi3620_clkmux_ops = {
+	.get_parent	= hi3620_clk_get_parent,
+	.set_parent	= hi3620_clk_set_parent,
+};
+
+static void __init hi3620_clkmux_setup(struct device_node *np)
+{
+	struct hi3620_muxclk *mclk;
+	struct clk_init_data *init;
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	u32 rdata[2];
+	u8 num_parents;
+	int i;
+
+	if (!hs_clk.sctrl)
+		return;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,hi3620-clkmux",
+				       &rdata[0], 2))
+		return;
+	/* get the count of items in mux */
+	for (i = 0; ; i++) {
+		/* parent's #clock-cells property is always 0 */
+		if (!of_parse_phandle(np, "clocks", i))
+			break;
+	}
+	parent_names = kzalloc(sizeof(char *) * i, GFP_KERNEL);
+	if (!parent_names)
+		return;
+
+	for (num_parents = i, i = 0; i < num_parents; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+
+	mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+	if (!mclk)
+		goto err;
+	init = kzalloc(sizeof(*init), GFP_KERNEL);
+	if (!init)
+		goto err_init;
+	init->name = kstrdup(clk_name, GFP_KERNEL);
+	init->ops = &hi3620_clkmux_ops;
+	init->flags = CLK_SET_RATE_PARENT;
+	init->parent_names = parent_names;
+	init->num_parents = num_parents;
+
+	mclk->reg = hs_clk.sctrl + rdata[0];
+	/* enable_mask bits are in higher 16bits */
+	mclk->mbits = rdata[1] << 16;
+	mclk->shift = ffs(rdata[1]) - 1;
+	mclk->width = fls(rdata[1]) - ffs(rdata[1]) + 1;
+	mclk->lock = &hs_clk.lock;
+	mclk->hw.init = init;
+
+	clk = clk_register(NULL, &mclk->hw);
+	if (IS_ERR(clk))
+		goto err_clk;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+	return;
+err_clk:
+	kfree(init);
+err_init:
+	kfree(mclk);
+err:
+	kfree(parent_names);
+}
+
+static void __init hs_clkgate_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names, *name;
+	unsigned long flags = 0;
+	u32 data[2];
+
+	if (!hs_clk.sctrl)
+		return;
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,clkgate",
+				       &data[0], 2))
+		return;
+	if (of_property_read_bool(np, "hisilicon,clkgate-inverted"))
+		flags = CLK_GATE_SET_TO_DISABLE;
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		return;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	clk = clk_register_gate(NULL, clk_name, parent_names[0], CLK_IS_BASIC,
+				hs_clk.sctrl + data[0], (u8)data[1], flags,
+				&hs_clk.lock);
+	if (IS_ERR(clk))
+		goto err;
+	if (!of_property_read_string(np, "clock-names", &name))
+		clk_register_clkdev(clk, name, NULL);
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err:
+	kfree(parent_names);
+}
+
+void __init hs_fixed_factor_clk_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	u32 data[2];
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,fixed-factor",
+				       data, 2))
+		return ;
+	/* gate only has the fixed parent */
+	parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
+	if (!parent_names)
+		return;
+	parent_names[0] = of_clk_get_parent_name(np, 0);
+
+	clk = clk_register_fixed_factor(NULL, clk_name, parent_names[0],
+					CLK_IS_BASIC, data[0], data[1]);
+	if (IS_ERR(clk))
+		goto err;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err:
+	kfree(parent_names);
+}
+
+void __init hs_divider_clk_setup(struct device_node *np)
+{
+	struct clk *clk;
+	const char *clk_name, **parent_names;
+	struct clk_div_table *table;
+	u8 shift, width;
+	unsigned int table_num;
+	int i;
+	u32 data[2];
+	const char *propname = "hisilicon,clkdiv-table";
+	const char *cellname = "#hisilicon,clkdiv-table-cells";
+	struct of_phandle_args div_table;
+
+	if (of_property_read_string(np, "clock-output-names", &clk_name))
+		return;
+	if (of_property_read_u32_array(np, "hisilicon,clkdiv",
+				       &data[0], 2))
+		return;
+
+	/*process the div_table*/
+	for (i = 0; ; i++) {
+		if (of_parse_phandle_with_args(np, propname, cellname,
+					       i, &div_table))
+			break;
+	}
+
+	/*table ends with <0, 0>, so plus one to table_num*/
+	table_num = i + 1;
+
+	table = kzalloc(sizeof(struct clk_div_table) * table_num, GFP_KERNEL);
+	if (!table)
+		return ;
+
+	for (i = 0; ; i++) {
+		if (of_parse_phandle_with_args(np, propname, cellname,
+					       i, &div_table))
+			break;
+
+		table[i].val = div_table.args[0];
+		table[i].div = div_table.args[1];
+	}
+
+	shift = ffs(data[1]) - 1;
+	width = fls(data[1]) - ffs(data[1]) + 1;
+
+	/* 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);
+
+	clk = clk_register_divider_table(NULL, clk_name, parent_names[0],
+					 CLK_IS_BASIC, hs_clk.sctrl + data[0],
+					 shift, width, 0,
+					 table, &hs_clk.lock);
+	if (IS_ERR(clk))
+		goto err_par;
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	return;
+err_par:
+	kfree(parent_names);
+err:
+	kfree(table);
+}
+
+static const __initconst struct of_device_id hs_clk_match[] = {
+	{
+		.compatible = "fixed-clock",
+		.data = of_fixed_clk_setup,
+	}, {
+		.compatible = "hisilicon,hi3620-clk-mux",
+		.data = hi3620_clkmux_setup,
+	}, {
+		.compatible = "hisilicon,hi3620-clk-gate",
+		.data = hi3620_clkgate_setup,
+	}, {
+		.compatible = "hisilicon,clk-gate",
+		.data = hs_clkgate_setup,
+	}, {
+		.compatible = "hisilicon,clk-div-table",
+		.data = hs_divider_clk_setup,
+	}, {
+		.compatible = "hisilicon,clk-fixed-factor",
+		.data = hs_fixed_factor_clk_setup,
+	},
+};
+
+void __init hs_init_clocks(void)
+{
+	struct device_node *node;
+
+	/*map pmctrl registers*/
+	node = of_find_compatible_node(NULL, NULL, "hisilicon,pmctrl");
+	hs_clk.pmctrl = of_iomap(node, 0);
+	WARN_ON(!hs_clk.pmctrl);
+
+	node = of_find_compatible_node(NULL, NULL, "hisilicon,sctrl");
+	hs_clk.sctrl = of_iomap(node, 0);
+
+	of_clk_init(hs_clk_match);
+}
-- 
1.7.10.4

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 2/7] clk: hs: add clock support Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  2013-02-28 11:04   ` Arnd Bergmann
  2013-02-28 21:46   ` Michal Simek
  2013-02-28  7:19 ` [PATCH 4/7] ARM: hs: enable hi4511 " Haojian Zhuang
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/Kconfig          |    2 ++
 arch/arm/Makefile         |    1 +
 arch/arm/mach-hs/Kconfig  |   23 +++++++++++++
 arch/arm/mach-hs/Makefile |    5 +++
 arch/arm/mach-hs/hs-dt.c  |   83 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 114 insertions(+)
 create mode 100644 arch/arm/mach-hs/Kconfig
 create mode 100644 arch/arm/mach-hs/Makefile
 create mode 100644 arch/arm/mach-hs/hs-dt.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dedf02b..dfe70aa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1055,6 +1055,8 @@ source "arch/arm/mach-h720x/Kconfig"
 
 source "arch/arm/mach-highbank/Kconfig"
 
+source "arch/arm/mach-hs/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
 source "arch/arm/mach-iop32x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ee4605f..08a913b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -149,6 +149,7 @@ machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
 machine-$(CONFIG_ARCH_H720X)		+= h720x
 machine-$(CONFIG_ARCH_HIGHBANK)		+= highbank
+machine-$(CONFIG_ARCH_HS)		+= hs
 machine-$(CONFIG_ARCH_INTEGRATOR)	+= integrator
 machine-$(CONFIG_ARCH_IOP13XX)		+= iop13xx
 machine-$(CONFIG_ARCH_IOP32X)		+= iop32x
diff --git a/arch/arm/mach-hs/Kconfig b/arch/arm/mach-hs/Kconfig
new file mode 100644
index 0000000..491c6da
--- /dev/null
+++ b/arch/arm/mach-hs/Kconfig
@@ -0,0 +1,23 @@
+config ARCH_HS
+	bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select CACHE_L2X0
+	select CACHE_PL310
+	select PINCTRL
+	select PINCTRL_SINGLE
+	select SERIAL_AMBA_PL011
+	select SERIAL_AMBA_PL011_CONSOLE
+	help
+	  Support for Hisilicon Hi36xx/Hi37xx processor family
+
+if ARCH_HS
+
+config MACH_HS_DT
+	bool "Hisilicon Development Board"
+	default y
+	help
+	  Say 'Y' here if you want to support the Hisilicon Development
+	  Board. 
+
+endif
diff --git a/arch/arm/mach-hs/Makefile b/arch/arm/mach-hs/Makefile
new file mode 100644
index 0000000..d79ecb5
--- /dev/null
+++ b/arch/arm/mach-hs/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Hisilicon Hi36xx/Hi37xx processors line
+#
+
+obj-$(CONFIG_MACH_HS_DT)	+= hs-dt.o
diff --git a/arch/arm/mach-hs/hs-dt.c b/arch/arm/mach-hs/hs-dt.c
new file mode 100644
index 0000000..813ebb0
--- /dev/null
+++ b/arch/arm/mach-hs/hs-dt.c
@@ -0,0 +1,83 @@
+/*
+ * (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.h>
+#include <linux/clkdev.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+static struct of_device_id hs_timer_match[] __initdata = {
+	{ .compatible = "arm,sp804", },
+	{}
+};
+
+static struct clk_lookup sp804_lookup = {
+	.dev_id	= "sp804",
+	.clk	= NULL,
+};
+
+extern void __init hs_init_clocks(void);
+static void __init hs_timer_init(void)
+{
+	struct device_node *node = NULL;
+	void __iomem *base;
+	int irq;
+
+	hs_init_clocks();
+
+	node = of_find_matching_node(NULL, hs_timer_match);
+	WARN_ON(!node);
+	if (!node) {
+		pr_err("Failed to find sp804 timer\n");
+		return;
+	}
+	base = of_iomap(node, 0);
+	WARN_ON(!base);
+
+	/* timer0 is used as clock event, and timer1 is clock source. */
+	irq = irq_of_parse_and_map(node, 0);
+	WARN_ON(!irq);
+
+	sp804_lookup.clk = of_clk_get(node, 0);
+	clkdev_add(&sp804_lookup);
+
+	sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, "timer1");
+	sp804_clockevents_init(base, irq, "timer0");
+}
+
+static void __init hs_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *hs_compat[] __initdata = {
+	"hisilicon,hi3620-hi4511",
+	NULL,
+};
+
+DT_MACHINE_START(HS_DT, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)")
+	/* Maintainer: Haojian Zhuang <haojian.zhuang@linaro.org> */
+	.map_io		= debug_ll_io_init,
+	.init_irq	= irqchip_init,
+	.init_time	= hs_timer_init,
+	.init_machine	= hs_init,
+	.dt_compat	= hs_compat,
+MACHINE_END
-- 
1.7.10.4

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

* [PATCH 4/7] ARM: hs: enable hi4511 with device tree
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 2/7] clk: hs: add clock support Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 3/7] ARM: hs: add board support with device tree Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 5/7] document: append hisilicon clock binding Haojian Zhuang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Enable Hisilicon Hi4511 development platform with device tree support.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/boot/dts/Makefile    |    1 +
 arch/arm/boot/dts/hi3620.dtsi | 1114 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/hi4511.dts  |  738 +++++++++++++++++++++++++++
 3 files changed, 1853 insertions(+)
 create mode 100644 arch/arm/boot/dts/hi3620.dtsi
 create mode 100644 arch/arm/boot/dts/hi4511.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ee9fbe4..fdb9823 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -48,6 +48,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
 	exynos5440-ssdk5440.dtb
 dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
 	ecx-2000.dtb
+dtb-$(CONFIG_ARCH_HS) += hi4511.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
 	integratorcp.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 0000000..b00552c
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,1114 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Hisilicon Ltd.
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	osc32k: osc at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "osc32khz";
+	};
+	osc26m: osc at 1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "osc26mhz";
+	};
+	pclk: clk at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "apb_pclk";
+	};
+	pll_arm0: clk at 1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1600000000>;
+		clock-output-names = "armpll0";
+	};
+	pll_arm1: clk at 2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1600000000>;
+		clock-output-names = "armpll1";
+	};
+	pll_peri: clk at 3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1440000000>;
+		clock-output-names = "armpll2";
+	};
+	pll_usb: clk at 4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1440000000>;
+		clock-output-names = "armpll3";
+	};
+	pll_hdmi: clk at 5 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1188000000>;
+		clock-output-names = "armpll4";
+	};
+	pll_gpu: clk at 6 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1300000000>;
+		clock-output-names = "armpll5";
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		pmctrl: pmctrl at fca08000 {
+			compatible = "hisilicon,pmctrl";
+			reg = <0xfca08000 0x1000>;
+ 		};
+
+		sctrl: sctrl at fc802000 {
+			compatible = "hisilicon,sctrl";
+			reg = <0xfc802000 0x1000>;
+
+			refclk_uart0: refclk at 0 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "rclk_uart0";
+				/* each item value */
+				/* reg_offset, enable_bits */
+				hisilicon,hi3620-clkmux = <0x100 0x80>;
+			};
+			refclk_uart1: refclk at 1 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "rclk_uart1";
+				hisilicon,hi3620-clkmux = <0x100 0x100>;
+			};
+			refclk_uart2: refclk at 2 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "rclk_uart2";
+				hisilicon,hi3620-clkmux = <0x100 0x200>;
+			};
+			refclk_uart3: refclk at 3 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "rclk_uart3";
+				hisilicon,hi3620-clkmux = <0x100 0x400>;
+			};
+			refclk_uart4: refclk at 4 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &pclk>;
+				clock-output-names = "rclk_uart4";
+				hisilicon,hi3620-clkmux = <0x100 0x800>;
+			};
+			refclk_cfgaxi: refclk at 5 {
+				compatible = "hisilicon,clk-fixed-factor";
+				#clock-cells = <0>;
+				clocks = <&pll_peri>;
+				clock-output-names = "rclk_cfgaxi";
+				/*mult, div*/
+				hisilicon,fixed-factor = <1 30>;
+			};
+			refclk_spi0: refclk at 6 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &refclk_cfgaxi>;
+				clock-output-names = "rclk_spi0";
+				hisilicon,hi3620-clkmux = <0x100 0x1000>;
+			};
+			refclk_spi1: refclk at 7 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &refclk_cfgaxi>;
+				clock-output-names = "rclk_spi1";
+				hisilicon,hi3620-clkmux = <0x100 0x2000>;
+			};
+			refclk_spi2: refclk at 8 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc26m &refclk_cfgaxi>;
+				clock-output-names = "rclk_spi2";
+				hisilicon,hi3620-clkmux = <0x100 0x4000>;
+			};
+			refclk_pwm0: refclk at 9 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &osc26m>;
+				clock-output-names = "rclk_pwm0";
+				hisilicon,hi3620-clkmux = <0x104 0x400>;
+			};
+			refclk_pwm1: refclk at 10 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &osc26m>;
+				clock-output-names = "rclk_pwm1";
+				hisilicon,hi3620-clkmux = <0x104 0x800>;
+			};
+			refclk_tcxo: refclk at 11 {
+				compatible = "hisilicon,clk-fixed-factor";
+				#clock-cells = <0>;
+				clocks = <&osc26m>;
+				clock-output-names = "rclk_tcxo";
+				hisilicon,fixed-factor = <1 4>;
+			};
+			refclk_timer0: refclk at 12 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk01>;
+				clock-output-names = "rclk_tim0";
+				hisilicon,hi3620-clkmux = <0 0x8000>;
+			};
+			refclk_timer1: refclk at 13 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk01>;
+				clock-output-names = "rclk_tim1";
+				hisilicon,hi3620-clkmux = <0 0x20000>;
+			};
+			refclk_timer2: refclk at 14 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk23>;
+				clock-output-names = "rclk_tim2";
+				hisilicon,hi3620-clkmux = <0 0x80000>;
+			};
+			refclk_timer3: refclk at 15 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk23>;
+				clock-output-names = "rclk_tim3";
+				hisilicon,hi3620-clkmux = <0 0x200000>;
+			};
+			refclk_timer4: refclk at 16 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk45>;
+				clock-output-names = "rclk_tim4";
+				hisilicon,hi3620-clkmux = <0x18 0x1>;
+			};
+			refclk_timer5: refclk at 17 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk45>;
+				clock-output-names = "rclk_tim5";
+				hisilicon,hi3620-clkmux = <0x18 0x4>;
+			};
+			refclk_timer6: refclk at 18 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk67>;
+				clock-output-names = "rclk_tim6";
+				hisilicon,hi3620-clkmux = <0x18 0x10>;
+			};
+			refclk_timer7: refclk at 19 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk67>;
+				clock-output-names = "rclk_tim7";
+				hisilicon,hi3620-clkmux = <0x18 0x40>;
+			};
+			refclk_timer8: refclk at 20 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk89>;
+				clock-output-names = "rclk_tim8";
+				hisilicon,hi3620-clkmux = <0x18 0x100>;
+			};
+			refclk_timer9: refclk at 21 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&osc32k &timerclk89>;
+				clock-output-names = "rclk_tim9";
+				hisilicon,hi3620-clkmux = <0x18 0x400>;
+			};
+			refclk_shareAXI: refclk at 22 {
+				compatible = "hisilicon,hi3620-clk-mux";
+				#clock-cells = <0>;
+				clocks = <&pll_usb &pll_peri>;
+				clock-output-names = "rclk_shareAXI";
+				hisilicon,hi3620-clkmux = <0x24 0x8000>;
+			};
+			uartclk0: clkgate at 0 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_uart0>;
+				clock-output-names = "uartclk0";
+				/* reset_enable, reset_disable, bit_idx */
+				hisilicon,hi3620-clkreset = <0x98 16>;
+				/* clk_enable, clk_disable, bit_idx */
+				hisilicon,hi3620-clkgate = <0x40 16>;
+			};
+			uartclk1: clkgate at 1 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_uart1>;
+				clock-output-names = "uartclk1";
+				hisilicon,hi3620-clkreset = <0x98 17>;
+				hisilicon,hi3620-clkgate = <0x40 17>;
+			};
+			uartclk2: clkgate at 2 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_uart2>;
+				clock-output-names = "uartclk2";
+				hisilicon,hi3620-clkreset = <0x98 18>;
+				hisilicon,hi3620-clkgate = <0x40 18>;
+			};
+			uartclk3: clkgate at 3 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_uart3>;
+				clock-output-names = "uartclk3";
+				hisilicon,hi3620-clkreset = <0x98 19>;
+				hisilicon,hi3620-clkgate = <0x40 19>;
+			};
+			uartclk4: clkgate at 4 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_uart4>;
+				clock-output-names = "uartclk4";
+				hisilicon,hi3620-clkreset = <0x98 20>;
+				hisilicon,hi3620-clkgate = <0x40 20>;
+			};
+			gpioclk0: clkgate at 5 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk0";
+				hisilicon,hi3620-clkreset = <0x80 8>;
+				hisilicon,hi3620-clkgate = <0x20 8>;
+			};
+			gpioclk1: clkgate at 6 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk1";
+				hisilicon,hi3620-clkreset = <0x80 9>;
+				hisilicon,hi3620-clkgate = <0x20 9>;
+			};
+			gpioclk2: clkgate at 7 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk2";
+				hisilicon,hi3620-clkreset = <0x80 10>;
+				hisilicon,hi3620-clkgate = <0x20 10>;
+			};
+			gpioclk3: clkgate at 8 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk3";
+				hisilicon,hi3620-clkreset = <0x80 11>;
+				hisilicon,hi3620-clkgate = <0x20 11>;
+			};
+			gpioclk4: clkgate at 9 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk4";
+				hisilicon,hi3620-clkreset = <0x80 12>;
+				hisilicon,hi3620-clkgate = <0x20 12>;
+			};
+			gpioclk5: clkgate at 10 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk5";
+				hisilicon,hi3620-clkreset = <0x80 13>;
+				hisilicon,hi3620-clkgate = <0x20 13>;
+			};
+			gpioclk6: clkgate at 11 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk6";
+				hisilicon,hi3620-clkreset = <0x80 14>;
+				hisilicon,hi3620-clkgate = <0x20 14>;
+			};
+			gpioclk7: clkgate at 12 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk7";
+				hisilicon,hi3620-clkreset = <0x80 15>;
+				hisilicon,hi3620-clkgate = <0x20 15>;
+			};
+			gpioclk8: clkgate at 13 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk8";
+				hisilicon,hi3620-clkreset = <0x80 16>;
+				hisilicon,hi3620-clkgate = <0x20 16>;
+			};
+			gpioclk9: clkgate at 14 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk9";
+				hisilicon,hi3620-clkreset = <0x80 17>;
+				hisilicon,hi3620-clkgate = <0x20 17>;
+			};
+			gpioclk10: clkgate at 15 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk10";
+				hisilicon,hi3620-clkreset = <0x80 18>;
+				hisilicon,hi3620-clkgate = <0x20 18>;
+			};
+			gpioclk11: clkgate at 16 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk11";
+				hisilicon,hi3620-clkreset = <0x80 19>;
+				hisilicon,hi3620-clkgate = <0x20 19>;
+			};
+			gpioclk12: clkgate at 17 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk12";
+				hisilicon,hi3620-clkreset = <0x80 20>;
+				hisilicon,hi3620-clkgate = <0x20 20>;
+			};
+			gpioclk13: clkgate at 18 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk13";
+				hisilicon,hi3620-clkreset = <0x80 21>;
+				hisilicon,hi3620-clkgate = <0x20 21>;
+			};
+			gpioclk14: clkgate at 19 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk14";
+				hisilicon,hi3620-clkreset = <0x80 22>;
+				hisilicon,hi3620-clkgate = <0x20 22>;
+			};
+			gpioclk15: clkgate at 20 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk15";
+				hisilicon,hi3620-clkreset = <0x80 23>;
+				hisilicon,hi3620-clkgate = <0x20 23>;
+			};
+			gpioclk16: clkgate at 21 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk16";
+				hisilicon,hi3620-clkreset = <0x80 24>;
+				hisilicon,hi3620-clkgate = <0x20 24>;
+			};
+			gpioclk17: clkgate at 22 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk17";
+				hisilicon,hi3620-clkreset = <0x80 25>;
+				hisilicon,hi3620-clkgate = <0x20 25>;
+			};
+			gpioclk18: clkgate at 23 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk18";
+				hisilicon,hi3620-clkreset = <0x80 26>;
+				hisilicon,hi3620-clkgate = <0x20 26>;
+			};
+			gpioclk19: clkgate at 24 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk19";
+				hisilicon,hi3620-clkreset = <0x80 27>;
+				hisilicon,hi3620-clkgate = <0x20 27>;
+			};
+			gpioclk20: clkgate at 25 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk20";
+				hisilicon,hi3620-clkreset = <0x80 28>;
+				hisilicon,hi3620-clkgate = <0x20 28>;
+			};
+			gpioclk21: clkgate at 26 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&pclk>;
+				clock-output-names = "gpioclk21";
+				hisilicon,hi3620-clkreset = <0x80 29>;
+				hisilicon,hi3620-clkgate = <0x20 29>;
+			};
+			spiclk0: clkgate at 27 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_spi0>;
+				clock-output-names = "spiclk0";
+				hisilicon,hi3620-clkreset = <0x98 21>;
+				hisilicon,hi3620-clkgate = <0x40 21>;
+			};
+			spiclk1: clkgate at 28 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_spi1>;
+				clock-output-names = "spiclk1";
+				hisilicon,hi3620-clkreset = <0x98 22>;
+				hisilicon,hi3620-clkgate = <0x40 22>;
+			};
+			spiclk2: clkgate at 29 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_spi2>;
+				clock-output-names = "spiclk2";
+				hisilicon,hi3620-clkreset = <0x98 23>;
+				hisilicon,hi3620-clkgate = <0x40 23>;
+			};
+			pwmclk0: clkgate at 30 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_pwm0>;
+				clock-output-names = "pwmclk0";
+				hisilicon,hi3620-clkreset = <0x98 7>;
+				hisilicon,hi3620-clkgate = <0x40 7>;
+			};
+			pwmclk1: clkgate at 31 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_pwm1>;
+				clock-output-names = "pwmclk1";
+				hisilicon,hi3620-clkreset = <0x98 8>;
+				hisilicon,hi3620-clkgate = <0x40 8>;
+			};
+			timerclk01: clkgate at 32 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_tcxo>;
+				clock-output-names = "timerclk01";
+				hisilicon,hi3620-clkreset = <0x80 0>;
+				hisilicon,hi3620-clkgate = <0x20 0>;
+			};
+			timerclk23: clkgate at 33 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_tcxo>;
+				clock-output-names = "timerclk23";
+				hisilicon,hi3620-clkreset = <0x80 1>;
+				hisilicon,hi3620-clkgate = <0x20 2>;
+			};
+			timerclk45: clkgate at 34 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_tcxo>;
+				clock-output-names = "timerclk45";
+				hisilicon,hi3620-clkreset = <0x98 3>;
+				hisilicon,hi3620-clkgate = <0x40 3>;
+			};
+			timerclk67: clkgate at 35 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_tcxo>;
+				clock-output-names = "timerclk67";
+				hisilicon,hi3620-clkreset = <0x98 4>;
+				hisilicon,hi3620-clkgate = <0x40 4>;
+			};
+			timerclk89: clkgate at 36 {
+				compatible = "hisilicon,hi3620-clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_tcxo>;
+				clock-output-names = "timerclk89";
+				hisilicon,hi3620-clkreset = <0x98 5>;
+				hisilicon,hi3620-clkgate = <0x40 5>;
+			};
+			timclk0: clkgate at 37 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_timer0>;
+				clock-output-names = "timclk0";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 16>;
+			};
+			timclk1: clkgate at 38 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_timer1>;
+				clock-output-names = "timclk1";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 18>;
+			};
+			timclk2: clkgate at 39 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_timer2>;
+				clock-output-names = "timclk2";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 20>;
+			};
+			timclk3: clkgate at 40 {
+				compatible = "hisilicon,clk-gate";
+				#clock-cells = <0>;
+				clocks = <&refclk_timer3>;
+				clock-output-names = "timclk3";
+				hisilicon,clkgate-inverted;
+				hisilicon,clkgate = <0 22>;
+			};
+			dtable: clkdiv at 0 {
+				#hisilicon,clkdiv-table-cells = <2>;
+			};
+			div_shareaxi: clkdiv at 1 {
+				compatible = "hisilicon,clk-div-table";
+				#clock-cells = <0>;
+				clocks = <&refclk_shareAXI>;
+				clock-output-names = "shareAXI_div";
+				hisilicon,clkdiv-table = <
+					&dtable 0 1 &dtable 1 2 &dtable 2 3 &dtable 3 4
+					&dtable 4 5 &dtable 5 6 &dtable 6 7 &dtable 7 8
+					&dtable 8 9 &dtable 9 10 &dtable 10 11 &dtable 11 12
+					&dtable 12 13 &dtable 13 14 &dtable 14 15 &dtable 15 16
+					&dtable 16 17 &dtable 17 18 &dtable 18 19 &dtable 19 20
+					&dtable 20 21 &dtable 21 22 &dtable 22 23 &dtable 23 24
+					&dtable 24 25 &dtable 25 26 &dtable 26 27 &dtable 27 28
+					&dtable 28 29 &dtable 29 30 &dtable 30 31 &dtable 31 32>;
+				/* divider register offset, mask */
+				hisilicon,clkdiv = <0x100 0x1f>;
+			};
+			div_cfgaxi: clkdiv at 2 {
+				compatible = "hisilicon,clk-div-table";
+				#clock-cells = <0>;
+				clocks = <&div_shareaxi>;
+				clock-output-names = "cfgAXI_div";
+				hisilicon,clkdiv-table = <&dtable 0x01 2>;
+				hisilicon,clkdiv = <0x100 0x60>;
+			};
+ 		};
+
+		l2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0xfc10000 0x100000>;
+			interrupts = <0 15 4>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		intc: interrupt-controller at fc001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			/* gic dist base, gic cpu base */
+			reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
+		};
+
+		timer0: timer at fc800000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc800000 0x1000>;
+			/* timer00 & timer01 */
+			interrupts = <0 0 4>, <0 1 4>;
+			clocks = <&timclk0 &timclk1 &pclk>;
+			clock-names = "timer0", "timer1", "apb_pclk";
+			status = "disabled";
+		};
+
+		timer1: timer at fc801000 {
+			/*
+			 * Only used in NORMAL state, not available ins
+			 * SLOW or DOZE state.
+			 * The rate is fixed in 24MHz.
+			 */
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfc801000 0x1000>;
+			/* timer10 & timer11 */
+			interrupts = <0 2 4>, <0 3 4>;
+			clocks = <&timclk0 &timclk1 &pclk>;
+			clock-names = "timer0", "timer1", "apb_pclk";
+			status = "disabled";
+		};
+
+		timer2: timer at fca01000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca01000 0x1000>;
+			/* timer20 & timer21 */
+			interrupts = <0 4 4>, <0 5 4>;
+			clocks = <&timclk2 &timclk3 &pclk>;
+			clock-names = "timer0", "timer1", "apb_pclk";
+			status = "disabled";
+		};
+
+		timer3: timer at fca02000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca02000 0x1000>;
+			/* timer30 & timer31 */
+			interrupts = <0 6 4>, <0 7 4>;
+			clocks = <&timclk0 &timclk1 &pclk>;
+			clock-names = "timer0", "timer1", "apb_pclk";
+			status = "disabled";
+		};
+
+		timer4: timer at fca03000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0xfca03000 0x1000>;
+			/* timer40 & timer41 */
+			interrupts = <0 96 4>, <0 97 4>;
+			clocks = <&timclk0 &timclk1 &pclk>;
+			clock-names = "timer0", "timer1", "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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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";
+			status = "disable";
+		};
+
+		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..8e64371
--- /dev/null
+++ b/arch/arm/boot/dts/hi4511.dts
@@ -0,0 +1,738 @@
+/*
+ *  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/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on mem=512m earlyprintk";
+	};
+
+	memory {
+		reg = <0x00000000 0x20000000>;
+	};
+
+	amba {
+		timer0: timer at fc800000 {
+			status = "ok";
+		};
+
+		uart0: uart at fcb00000 {	/* console */
+/*
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>;
+			pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>;
+*/
+			status = "ok";
+		};
+
+		uart1: uart at fcb01000 { /* modem */
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>;
+			pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>;
+			status = "ok";
+		};
+
+		uart2: uart at fcb02000 { /* audience */
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>;
+			pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>;
+			status = "ok";
+		};
+
+		uart3: uart at fcb03000 {
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
+			pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>;
+			status = "ok";
+		};
+
+		uart4: uart at fcb04000 {
+			pinctrl-names = "default", "idle";
+			pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>;
+			pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>;
+			status = "ok";
+		};
+
+		gpio0: gpio at fc806000 {
+			status = "ok";
+		};
+
+		gpio1: gpio at fc807000 {
+			status = "ok";
+		};
+
+		gpio2: gpio at fc808000 {
+			status = "ok";
+		};
+
+		gpio3: gpio at fc809000 {
+			status = "ok";
+		};
+
+		gpio4: gpio at fc80a000 {
+			status = "ok";
+		};
+
+		gpio5: gpio at fc80b000 {
+			status = "ok";
+		};
+
+		gpio6: gpio at fc80c000 {
+			status = "ok";
+		};
+
+		gpio7: gpio at fc80d000 {
+			status = "ok";
+		};
+
+		gpio8: gpio at fc80e000 {
+			status = "ok";
+		};
+
+		gpio9: gpio at fc80f000 {
+			status = "ok";
+		};
+
+		gpio10: gpio at fc810000 {
+			status = "ok";
+		};
+
+		gpio11: gpio at fc811000 {
+			status = "ok";
+		};
+
+		gpio12: gpio at fc812000 {
+			status = "ok";
+		};
+
+		gpio13: gpio at fc813000 {
+			status = "ok";
+		};
+
+		gpio14: gpio at fc814000 {
+			status = "ok";
+		};
+
+		gpio15: gpio at fc815000 {
+			status = "ok";
+		};
+
+		gpio16: gpio at fc816000 {
+			status = "ok";
+		};
+
+		gpio17: gpio at fc817000 {
+			status = "ok";
+		};
+
+		gpio18: gpio at fc818000 {
+			status = "ok";
+		};
+
+		gpio19: gpio at fc819000 {
+			status = "ok";
+		};
+
+		gpio20: gpio at fc81a000 {
+			status = "ok";
+		};
+
+		gpio21: gpio at fc81b000 {
+			status = "ok";
+		};
+
+		gpio-keys {
+			compatible = "gpio-keys";
+
+			call {
+				label = "call";
+				gpios = <&gpio17 2 0>;
+				linux,code = <169>;	/* KEY_PHONE */
+			};
+		};
+
+		pmx0: pinmux at fc803000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pmx_func>;
+
+			board_pmx_pins: pinmux_board_pmx_pins {
+				pinctrl-single,pins = <
+					0x008 0x0	/* GPIO -- eFUSE_DOUT */
+					0x100 0x0	/* USIM_CLK & USIM_DATA (IOMG63) */
+					0x104 0x0	/* USIM_RST (IOMG96) */
+				>;
+			};
+			uart0_pmx_func: pinmux_uart0_pins at 0  {
+				pinctrl-single,pins = <
+					0x0f0 0x0
+					0x0f4 0x0	/* UART0_RX & UART0_TX */
+				>;
+			};
+			uart0_pmx_idle: pinmux_uart0_pins at 1 {
+				pinctrl-single,pins = <
+					/*0x0f0 0x1*/	/* UART0_CTS & UART0_RTS */
+					0x0f4 0x1	/* UART0_RX & UART0_TX */
+				>;
+			};
+			uart1_pmx_func: pinmux_uart1_pins at 0  {
+				pinctrl-single,pins = <
+					0x0f8 0x0	/* UART1_CTS & UART1_RTS (IOMG61) */
+					0x0fc 0x0	/* UART1_RX & UART1_TX (IOMG62) */
+				>;
+			};
+			uart1_pmx_idle: pinmux_uart1_pins at 1  {
+				pinctrl-single,pins = <
+					0x0f8 0x1	/* GPIO (IOMG61) */
+					0x0fc 0x1	/* GPIO (IOMG62) */
+				>;
+			};
+			uart2_pmx_func: pinmux_uart2_pins at 0 {
+				pinctrl-single,pins = <
+					0x104 0x2	/* UART2_RXD (IOMG96) */
+					0x108 0x2	/* UART2_TXD (IOMG64) */
+				>;
+			};
+			uart2_pmx_idle: pinmux_uart2_pins at 1 {
+				pinctrl-single,pins = <
+					0x104 0x1	/* GPIO (IOMG96) */
+					0x108 0x1	/* GPIO (IOMG64) */
+				>;
+			};
+			uart3_pmx_func: pinmux_uart3_pins at 0 {
+				pinctrl-single,pins = <
+					0x160 0x2	/* UART3_CTS & UART3_RTS (IOMG85) */
+					0x164 0x2	/* UART3_RXD & UART3_TXD (IOMG86) */
+				>;
+			};
+			uart3_pmx_idle: pinmux_uart3_pins at 1 {
+				pinctrl-single,pins = <
+					0x160 0x1	/* GPIO (IOMG85) */
+					0x164 0x1	/* GPIO (IOMG86) */
+				>;
+			};
+			uart4_pmx_func: pinmux_uart4_pins at 0 {
+				pinctrl-single,pins = <
+					0x168 0x0	/* UART4_CTS & UART4_RTS (IOMG87) */
+					0x16c 0x0	/* UART4_RXD (IOMG88) */
+					0x170 0x0	/* UART4_TXD (IOMG93) */
+				>;
+			};
+			uart4_pmx_idle: pinmux_uart4_pins at 1 {
+				pinctrl-single,pins = <
+					0x168 0x1	/* GPIO (IOMG87) */
+					0x16c 0x1	/* GPIO (IOMG88) */
+					0x170 0x1	/* GPIO (IOMG93) */
+				>;
+			};
+			i2c0_pmx_func: pinmux_i2c0_pins at 0 {
+				pinctrl-single,pins = <
+					0x0b4 0x0	/* I2C0_SCL & I2C0_SDA (IOMG45) */
+				>;
+			};
+			i2c0_pmx_idle: pinmux_i2c0_pins at 1 {
+				pinctrl-single,pins = <
+					0x0b4 0x1	/* GPIO (IOMG45) */
+				>;
+			};
+			i2c1_pmx_func: pinmux_i2c1_pins at 0 {
+				pinctrl-single,pins = <
+					0x0b8 0x0	/* I2C1_SCL & I2C1_SDA (IOMG46) */
+				>;
+			};
+			i2c1_pmx_idle: pinmux_i2c1_pins at 1 {
+				pinctrl-single,pins = <
+					0x0b8 0x1	/* GPIO (IOMG46) */
+				>;
+			};
+			i2c2_pmx_func: pinmux_i2c2_pins at 0 {
+				pinctrl-single,pins = <
+					0x068 0x0	/* I2C2_SCL (IOMG26) */
+					0x06c 0x0	/* I2C2_SDA (IOMG27) */
+				>;
+			};
+			i2c2_pmx_idle: pinmux_i2c2_pins at 0 {
+				pinctrl-single,pins = <
+					0x068 0x1	/* GPIO (IOMG26) */
+					0x06c 0x1	/* GPIO (IOMG27) */
+				>;
+			};
+			i2c3_pmx_func: pinmux_i2c3_pins at 0 {
+				pinctrl-single,pins = <
+					0x050 0x2	/* I2C3_SCL (IOMG20) */
+					0x054 0x2	/* I2C3_SDA (IOMG21) */
+				>;
+			};
+			i2c3_pmx_idle: pinmux_i2c3_pins at 0 {
+				pinctrl-single,pins = <
+					0x050 0x1	/* GPIO (IOMG20) */
+					0x054 0x1	/* GPIO (IOMG21) */
+				>;
+			};
+			spi0_pmx_func: pinmux_spi0_pins at 0 {
+				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: pinmux_spi0_pins at 1 {
+				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: pinmux_spi1_pins at 0 {
+				pinctrl-single,pins = <
+					0x184 0x0	/* SPI1_CLK/SPI1_DI (IOMG98) */
+					0x0e8 0x0	/* SPI1_DO (IOMG58) */
+					0x0ec 0x0	/* SPI1_CS (IOMG95) */
+				>;
+			};
+			spi1_pmx_idle: pinmux_spi1_pins at 1 {
+				pinctrl-single,pins = <
+					0x184 0x1	/* GPIO (IOMG98) */
+					0x0e8 0x1	/* GPIO (IOMG58) */
+					0x0ec 0x1	/* GPIO (IOMG95) */
+				>;
+			};
+			kpc_pmx_func: pinmux_kpc_pins at 0 {
+				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: pinmux_kpc_pins at 1 {
+				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: pinmux_gpiokey_pins {
+				pinctrl-single,pins = <
+					0x10c 0x1	/* KEY_OUT0/GPIO (IOMG65) */
+					0x130 0x1	/* KEY_IN1/GPIO (IOMG74) */
+				>;
+			};
+			emmc_pmx_func: pinmux_emmc_pins at 0 {
+				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: pinmux_emmc_pins at 1 {
+				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: pinmux_sd_pins at 0 {
+				pinctrl-single,pins = <
+					0x0bc 0x0	/* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */
+					0x0c0 0x0	/* SD_DATA3 (IOMG48) */
+				>;
+			};
+			sd_pmx_idle: pinmux_sd_pins at 1 {
+				pinctrl-single,pins = <
+					0x0bc 0x1	/* GPIO (IOMG47) */
+					0x0c0 0x1	/* GPIO (IOMG48) */
+				>;
+			};
+			nand_pmx_func: pinmux_nand_pins at 0 {
+				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: pinmux_nand_pins at 1 {
+				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: pinmux_sdio_pins at 0 {
+				pinctrl-single,pins = <
+					0x0c4 0x0	/* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */
+				>;
+			};
+			sdio_pmx_idle: pinmux_sdio_pins at 1 {
+				pinctrl-single,pins = <
+					0x0c4 0x1	/* GPIO (IOMG49) */
+				>;
+			};
+			audio_out_pmx_func: pinmux_audio_pins at 0 {
+				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: pinmux_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: pinmux_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: pinmux_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: pinmux_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: pinmux_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: pinmux_uart0_pins at 2 {
+				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: pinmux_uart0_pins at 3 {
+				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: pinmux_uart1_pins at 2 {
+				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: pinmux_uart1_pins at 3 {
+				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: pinmux_uart2_pins at 2 {
+				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: pinmux_uart2_pins at 3 {
+				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: pinmux_uart3_pins at 2 {
+				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: pinmux_uart3_pins at 3 {
+				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: pinmux_uart4_pins at 2 {
+				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: pinmux_i2c0_pins at 2 {
+				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: pinmux_i2c1_pins at 2 {
+				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: pinmux_i2c2_pins at 2 {
+				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: pinmux_i2c3_pins at 2 {
+				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: pinmux_spi0_pins at 2 {
+				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: pinmux_spi0_pins at 3 {
+				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: pinmux_spi1_pins at 2 {
+				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: pinmux_spi1_pins at 3 {
+				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: pinmux_kpc_pins at 2 {
+				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: pinmux_emmc_pins at 2 {
+				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: pinmux_sd_pins at 2 {
+				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: pinmux_sd_pins at 3 {
+				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: pinmux_nand_pins at 2 {
+				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: pinmux_nand_pins at 3 {
+				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: pinmux_sdio_pins at 2 {
+				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: pinmux_audio_pins at 1 {
+				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>;
+			};
+		};
+	};
+};
-- 
1.7.10.4

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

* [PATCH 5/7] document: append hisilicon clock binding
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
                   ` (2 preceding siblings ...)
  2013-02-28  7:19 ` [PATCH 4/7] ARM: hs: enable hi4511 " Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 6/7] Document: dts: create hisilicon document Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 7/7] ARM: config: append arch hs into multi defconfig Haojian Zhuang
  5 siblings, 0 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Add hisilicon clock binding document for device tree.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../devicetree/bindings/clock/hisilicon.txt        |   73 ++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hisilicon.txt

diff --git a/Documentation/devicetree/bindings/clock/hisilicon.txt b/Documentation/devicetree/bindings/clock/hisilicon.txt
new file mode 100644
index 0000000..04fefc3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon.txt
@@ -0,0 +1,73 @@
+Device Tree Clock bindings for arch-vt8500
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties for mux clocks:
+ - compatible : Shall be "hisilicon,hi3620-clk-mux".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,hi3620-mux : array of mux register offset & mask bits
+
+Required properties for Hi3620 gate clocks:
+ - compatible : Shall be "hisilicon,hi3620-clk-gate".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,hi3620-clkgate : array of enable register offset & enable bit
+ - hisilicon,hi3620-clkreset : array of reset register offset & enable bit
+
+Required properties for gate clocks:
+ - compatible : Shall be "hisilicon,clk-gate".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,clkgate-inverted : bool value. True means that set-to-disable.
+
+Required properties for clock divider:
+ - compatible : Shall be "hisilicon,clk-div-table".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - #hisilicon,clkdiv-table-cells : the number of parameters after phandle in
+   hisilicon,clkdiv-table property.
+ - hisilicon,clkdiv-table : list of value that are used to configure clock
+   divider. They're value of phandle, index & divider value.
+ - hisilicon,clkdiv : array of divider register offset & mask bits.
+
+Required properties for clock fixed factor divider:
+ - compatible : Shall be "hisilicon,fixed-factor".
+ - clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+ - clock-output-names : shall be reference name.
+ - #clock-cells : from common clock binding; shall be set to 0.
+ - hisilicon,fixed-factor : array of multiplier & divider.
+
+For example:
+	timclk1: clkgate at 38 {
+		compatible = "hisilicon,clk-gate";
+		#clock-cells = <0>;
+		clocks = <&refclk_timer1>;
+		clock-output-names = "timclk1";
+		hisilicon,clkgate-inverted;
+		hisilicon,clkgate = <0 18>;
+	};
+
+	dtable: clkdiv at 0 {
+		#hisilicon,clkdiv-table-cells = <2>;
+	};
+
+	div_cfgaxi: clkdiv at 2 {
+		compatible = "hisilicon,clk-div-table";
+		#clock-cells = <0>;
+		clocks = <&div_shareaxi>;
+		clock-output-names = "cfgAXI_div";
+		hisilicon,clkdiv-table = <&dtable 0x01 2>;
+		hisilicon,clkdiv = <0x100 0x60>;
+	};
-- 
1.7.10.4

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

* [PATCH 6/7] Document: dts: create hisilicon document
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
                   ` (3 preceding siblings ...)
  2013-02-28  7:19 ` [PATCH 5/7] document: append hisilicon clock binding Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  2013-02-28  7:19 ` [PATCH 7/7] ARM: config: append arch hs into multi defconfig Haojian Zhuang
  5 siblings, 0 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Append the illustration on two boards from hisilicon.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Documentation/devicetree/bindings/arm/hs/hisilicon.txt |   10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/hs/hisilicon.txt

diff --git a/Documentation/devicetree/bindings/arm/hs/hisilicon.txt b/Documentation/devicetree/bindings/arm/hs/hisilicon.txt
new file mode 100644
index 0000000..3be60c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/hs/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";
-- 
1.7.10.4

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

* [PATCH 7/7] ARM: config: append arch hs into multi defconfig
  2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
                   ` (4 preceding siblings ...)
  2013-02-28  7:19 ` [PATCH 6/7] Document: dts: create hisilicon document Haojian Zhuang
@ 2013-02-28  7:19 ` Haojian Zhuang
  5 siblings, 0 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Append ARCH_HS (Hisilicon SoC) into multi_v7_defconfig.

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

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index e31d442..dc1ad68 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -5,6 +5,8 @@ CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_HIGHBANK=y
+CONFIG_MACH_HI4511=y
+CONFIG_ARCH_HS=y
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_ARCH_SUNXI=y
 # CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
-- 
1.7.10.4

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28  7:19 ` [PATCH 3/7] ARM: hs: add board support with device tree Haojian Zhuang
@ 2013-02-28 11:04   ` Arnd Bergmann
  2013-02-28 12:55     ` Haojian Zhuang
  2013-02-28 21:46   ` Michal Simek
  1 sibling, 1 reply; 13+ messages in thread
From: Arnd Bergmann @ 2013-02-28 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 28 February 2013, Haojian Zhuang wrote:
> Add board support with device tree for Hisilicon Hi36xx/Hi37xx platform.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Ah, nice and small ;-)

>  arch/arm/Kconfig          |    2 ++
>  arch/arm/Makefile         |    1 +
>  arch/arm/mach-hs/Kconfig  |   23 +++++++++++++
>  arch/arm/mach-hs/Makefile |    5 +++
>  arch/arm/mach-hs/hs-dt.c  |   83 +++++++++++++++++++++++++++++++++++++++++++++

Regarding the naming, I wonder if "hs" is unique enough for a platform name.
AFAIK, HiSilicon has a couple of independently developed SoC families,
so we might want to be a bit more specific here, e.g. mach-hi3xxx.

Regarding the file name, I think the "-dt" postfix is redundant, when we
only support booting using DT. I would call this one the same thing as the
platform name, whichever we go with.

> +config MACH_HS_DT
> +	bool "Hisilicon Development Board"
> +	default y
> +	help
> +	  Say 'Y' here if you want to support the Hisilicon Development
> +	  Board. 
> +
> +endif

I don't think we need this option. Let's just always build the file
when the platform is enabled, and build all .dtb files as well.

> +static struct clk_lookup sp804_lookup = {
> +	.dev_id	= "sp804",
> +	.clk	= NULL,
> +};

(adding Mike to Cc)

Shouldn't the clk_lookup be automatic with a fully DT enabled platform now?

> +extern void __init hs_init_clocks(void);
> +static void __init hs_timer_init(void)
> +{
> +	struct device_node *node = NULL;
> +	void __iomem *base;
> +	int irq;
> +
> +	hs_init_clocks();
> +
> +	node = of_find_matching_node(NULL, hs_timer_match);
> +	WARN_ON(!node);
> +	if (!node) {
> +		pr_err("Failed to find sp804 timer\n");
> +		return;
> +	}
> +	base = of_iomap(node, 0);
> +	WARN_ON(!base);
> +
> +	/* timer0 is used as clock event, and timer1 is clock source. */
> +	irq = irq_of_parse_and_map(node, 0);
> +	WARN_ON(!irq);
> +
> +	sp804_lookup.clk = of_clk_get(node, 0);
> +	clkdev_add(&sp804_lookup);
> +
> +	sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, "timer1");
> +	sp804_clockevents_init(base, irq, "timer0");
> +}

I think for the clocksource/clockevents driver, we should move
arch/arm/common/timer-sp.c to drivers/clocksource now and integrate
it into the automatic probing through clocksource_of_init().

> +static void __init hs_init(void)
> +{
> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}
> +
> +static const char *hs_compat[] __initdata = {
> +	"hisilicon,hi3620-hi4511",
> +	NULL,
> +};
> +
> +DT_MACHINE_START(HS_DT, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)")
> +	/* Maintainer: Haojian Zhuang <haojian.zhuang@linaro.org> */
> +	.map_io		= debug_ll_io_init,
> +	.init_irq	= irqchip_init,
> +	.init_time	= hs_timer_init,
> +	.init_machine	= hs_init,
> +	.dt_compat	= hs_compat,
> +MACHINE_END

This looks right at the moment, but I also have a patch to make it possible to drop the
irqchip_init, clocksource_of_init and hs_init() calls here, as they are all the
defaults. At that point, the platform would be essentially empty except for the
debug_ll_io_init part that is inherently platform specific. 

	Arnd

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

* [PATCH 2/7] clk: hs: add clock support
  2013-02-28  7:19 ` [PATCH 2/7] clk: hs: add clock support Haojian Zhuang
@ 2013-02-28 12:48   ` Haojian Zhuang
  0 siblings, 0 replies; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28 12:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 February 2013 15:19, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
> Add clock support with device tree on Hisilicon SoC.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  drivers/clk/Makefile |    1 +
>  drivers/clk/clk-hs.c |  463 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 464 insertions(+)
>  create mode 100644 drivers/clk/clk-hs.c
>
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 300d477..2d3a08d 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK)      += clk-mux.o
>  obj-$(CONFIG_ARCH_BCM2835)     += clk-bcm2835.o
>  obj-$(CONFIG_ARCH_NOMADIK)     += clk-nomadik.o
>  obj-$(CONFIG_ARCH_HIGHBANK)    += clk-highbank.o
> +obj-$(CONFIG_ARCH_HS)          += clk-hs.o
>  obj-$(CONFIG_ARCH_MXS)         += mxs/
>  obj-$(CONFIG_ARCH_SOCFPGA)     += socfpga/
>  obj-$(CONFIG_PLAT_SPEAR)       += spear/
> diff --git a/drivers/clk/clk-hs.c b/drivers/clk/clk-hs.c
> new file mode 100644
> index 0000000..e802bf4
> --- /dev/null
> +++ b/drivers/clk/clk-hs.c
> @@ -0,0 +1,463 @@
> +/*
> + * Hisilicon clock driver
> + *
> + * Copyright (c) 2012-2013 Hisilicon Limited.
> + * Copyright (c) 2012-2013 Linaro Limited.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *        Xin Li <li.xin@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clk-private.h>
> +#include <linux/clkdev.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +
> +#define HI3620_DISABLE_OFF             0x4
> +#define HI3620_STATUS_OFF              0x8
> +
> +struct hi3620_periclk {
> +       struct clk_hw   hw;
> +       void __iomem    *enable;        /* enable register */
> +       void __iomem    *reset;         /* reset register */
> +       u32             ebits;          /* bits in enable/disable register */
> +       u32             rbits;          /* bits in reset/unreset register */
> +       spinlock_t      *lock;
> +};
> +
> +struct hi3620_muxclk {
> +       struct clk_hw   hw;
> +       void __iomem    *reg;           /* mux register */
> +       u8              shift;
> +       u8              width;
> +       u32             ebits;          /* enable bits in mux register */
> +       u32             mbits;          /* mask bits in mux register */
> +       spinlock_t      *lock;
> +};
> +
> +struct hs_clk {
> +       void __iomem    *pmctrl;
> +       void __iomem    *sctrl;
> +       spinlock_t      lock;
> +};
> +
> +static struct hs_clk hs_clk;
> +
> +static int hi3620_clkgate_prepare(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
> +       writel_relaxed(pclk->rbits, pclk->reset + HI3620_DISABLE_OFF);
> +       readl_relaxed(pclk->reset + HI3620_STATUS_OFF);
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +       return 0;
> +}
> +
> +static int hi3620_clkgate_enable(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       writel_relaxed(pclk->ebits, pclk->enable);
> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +       return 0;
> +}
> +
> +static void hi3620_clkgate_disable(struct clk_hw *hw)
> +{
> +       struct hi3620_periclk *pclk;
> +       unsigned long flags = 0;
> +
> +       pclk = container_of(hw, struct hi3620_periclk, hw);
> +       if (pclk->lock)
> +               spin_lock_irqsave(pclk->lock, flags);
> +       writel_relaxed(pclk->ebits, pclk->enable + HI3620_DISABLE_OFF);
> +       readl_relaxed(pclk->enable + HI3620_STATUS_OFF);
> +       if (pclk->lock)
> +               spin_unlock_irqrestore(pclk->lock, flags);
> +}
> +
> +static struct clk_ops hi3620_clkgate_ops = {
> +       .prepare        = hi3620_clkgate_prepare,
> +       .enable         = hi3620_clkgate_enable,
> +       .disable        = hi3620_clkgate_disable,
> +};
> +
> +static void __init hi3620_clkgate_setup(struct device_node *np)
> +{
> +       struct hi3620_periclk *pclk;
> +       struct clk_init_data *init;
> +       struct clk *clk;
> +       const char *clk_name, *name, **parent_names;
> +       u32 rdata[2], gdata[2];
> +
> +       if (!hs_clk.sctrl)
> +               return;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,hi3620-clkreset",
> +                                      &rdata[0], 2))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,hi3620-clkgate",
> +                                      &gdata[0], 2))
> +               return;
> +       if (rdata[1] >= 32 || gdata[1] >= 32)
> +               return;
> +
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +
> +       pclk = kzalloc(sizeof(*pclk), GFP_KERNEL);
> +       if (!pclk)
> +               goto err;
> +
> +       init = kzalloc(sizeof(*init), GFP_KERNEL);
> +       if (!init)
> +               goto err_pclk;
> +       init->name = kstrdup(clk_name, GFP_KERNEL);
> +       init->ops = &hi3620_clkgate_ops;
> +       init->flags = CLK_SET_RATE_PARENT;
> +       init->parent_names = parent_names;
> +       init->num_parents = 1;
> +
> +       pclk->reset = hs_clk.sctrl + rdata[0];
> +       pclk->rbits = 1 << rdata[1];
> +       pclk->enable = hs_clk.sctrl + gdata[0];
> +       pclk->ebits = 1 << gdata[1];
> +       pclk->lock = &hs_clk.lock;
> +       pclk->hw.init = init;
> +
> +       clk = clk_register(NULL, &pclk->hw);
> +       if (IS_ERR(clk))
> +               goto err_init;
> +       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_init:
> +       kfree(init);
> +err_pclk:
> +       kfree(pclk);
> +err:
> +       kfree(parent_names);
> +}
> +
> +static u8 hi3620_clk_get_parent(struct clk_hw *hw)
> +{
> +       struct hi3620_muxclk *mclk;
> +       u32 data;
> +       unsigned long flags = 0;
> +
> +       mclk = container_of(hw, struct hi3620_muxclk, hw);
> +
> +       if (mclk->lock)
> +               spin_lock_irqsave(mclk->lock, flags);
> +
> +       data = readl_relaxed(mclk->reg) >> mclk->shift;
> +       data &= (1 << mclk->width) - 1;
> +
> +       if (mclk->lock)
> +               spin_unlock_irqrestore(mclk->lock, flags);
> +
> +       if (data >= __clk_get_num_parents(hw->clk))
> +               return -EINVAL;
> +
> +       return (u8)data;
> +}
> +
> +static int hi3620_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct hi3620_muxclk *mclk;
> +       u32 data;
> +       unsigned long flags = 0;
> +
> +       mclk = container_of(hw, struct hi3620_muxclk, hw);
> +
> +       if (mclk->lock)
> +               spin_lock_irqsave(mclk->lock, flags);
> +
> +       data = readl_relaxed(mclk->reg);
> +       data &= ~(((1 << mclk->width) - 1) << mclk->shift);
> +       data |= index << mclk->shift;
> +       writel_relaxed(data, mclk->reg);
> +       /* set mask enable bits */
> +       data |= mclk->mbits;
> +       writel_relaxed(data, mclk->reg);
> +
> +       if (mclk->lock)
> +               spin_unlock_irqrestore(mclk->lock, flags);
> +
> +       return 0;
> +}
> +
> +static struct clk_ops hi3620_clkmux_ops = {
> +       .get_parent     = hi3620_clk_get_parent,
> +       .set_parent     = hi3620_clk_set_parent,
> +};
> +
> +static void __init hi3620_clkmux_setup(struct device_node *np)
> +{
> +       struct hi3620_muxclk *mclk;
> +       struct clk_init_data *init;
> +       struct clk *clk;
> +       const char *clk_name, **parent_names;
> +       u32 rdata[2];
> +       u8 num_parents;
> +       int i;
> +
> +       if (!hs_clk.sctrl)
> +               return;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,hi3620-clkmux",
> +                                      &rdata[0], 2))
> +               return;
> +       /* get the count of items in mux */
> +       for (i = 0; ; i++) {
> +               /* parent's #clock-cells property is always 0 */
> +               if (!of_parse_phandle(np, "clocks", i))
> +                       break;
> +       }
> +       parent_names = kzalloc(sizeof(char *) * i, GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +
> +       for (num_parents = i, i = 0; i < num_parents; i++)
> +               parent_names[i] = of_clk_get_parent_name(np, i);
> +
> +       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
> +       if (!mclk)
> +               goto err;
> +       init = kzalloc(sizeof(*init), GFP_KERNEL);
> +       if (!init)
> +               goto err_init;
> +       init->name = kstrdup(clk_name, GFP_KERNEL);
> +       init->ops = &hi3620_clkmux_ops;
> +       init->flags = CLK_SET_RATE_PARENT;
> +       init->parent_names = parent_names;
> +       init->num_parents = num_parents;
> +
> +       mclk->reg = hs_clk.sctrl + rdata[0];
> +       /* enable_mask bits are in higher 16bits */
> +       mclk->mbits = rdata[1] << 16;
> +       mclk->shift = ffs(rdata[1]) - 1;
> +       mclk->width = fls(rdata[1]) - ffs(rdata[1]) + 1;
> +       mclk->lock = &hs_clk.lock;
> +       mclk->hw.init = init;
> +
> +       clk = clk_register(NULL, &mclk->hw);
> +       if (IS_ERR(clk))
> +               goto err_clk;
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +
> +       return;
> +err_clk:
> +       kfree(init);
> +err_init:
> +       kfree(mclk);
> +err:
> +       kfree(parent_names);
> +}
> +
> +static void __init hs_clkgate_setup(struct device_node *np)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names, *name;
> +       unsigned long flags = 0;
> +       u32 data[2];
> +
> +       if (!hs_clk.sctrl)
> +               return;
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,clkgate",
> +                                      &data[0], 2))
> +               return;
> +       if (of_property_read_bool(np, "hisilicon,clkgate-inverted"))
> +               flags = CLK_GATE_SET_TO_DISABLE;
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +
> +       clk = clk_register_gate(NULL, clk_name, parent_names[0], CLK_IS_BASIC,
> +                               hs_clk.sctrl + data[0], (u8)data[1], flags,
> +                               &hs_clk.lock);
> +       if (IS_ERR(clk))
> +               goto err;
> +       if (!of_property_read_string(np, "clock-names", &name))
> +               clk_register_clkdev(clk, name, NULL);
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err:
> +       kfree(parent_names);
> +}
> +
> +void __init hs_fixed_factor_clk_setup(struct device_node *np)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names;
> +       u32 data[2];
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,fixed-factor",
> +                                      data, 2))
> +               return ;
> +       /* gate only has the fixed parent */
> +       parent_names = kzalloc(sizeof(char *), GFP_KERNEL);
> +       if (!parent_names)
> +               return;
> +       parent_names[0] = of_clk_get_parent_name(np, 0);
> +
> +       clk = clk_register_fixed_factor(NULL, clk_name, parent_names[0],
> +                                       CLK_IS_BASIC, data[0], data[1]);
> +       if (IS_ERR(clk))
> +               goto err;
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err:
> +       kfree(parent_names);
> +}
> +
> +void __init hs_divider_clk_setup(struct device_node *np)
> +{
> +       struct clk *clk;
> +       const char *clk_name, **parent_names;
> +       struct clk_div_table *table;
> +       u8 shift, width;
> +       unsigned int table_num;
> +       int i;
> +       u32 data[2];
> +       const char *propname = "hisilicon,clkdiv-table";
> +       const char *cellname = "#hisilicon,clkdiv-table-cells";
> +       struct of_phandle_args div_table;
> +
> +       if (of_property_read_string(np, "clock-output-names", &clk_name))
> +               return;
> +       if (of_property_read_u32_array(np, "hisilicon,clkdiv",
> +                                      &data[0], 2))
> +               return;
> +
> +       /*process the div_table*/
> +       for (i = 0; ; i++) {
> +               if (of_parse_phandle_with_args(np, propname, cellname,
> +                                              i, &div_table))
> +                       break;
> +       }
> +
> +       /*table ends with <0, 0>, so plus one to table_num*/
> +       table_num = i + 1;
> +
> +       table = kzalloc(sizeof(struct clk_div_table) * table_num, GFP_KERNEL);
> +       if (!table)
> +               return ;
> +
> +       for (i = 0; ; i++) {
> +               if (of_parse_phandle_with_args(np, propname, cellname,
> +                                              i, &div_table))
> +                       break;
> +
> +               table[i].val = div_table.args[0];
> +               table[i].div = div_table.args[1];
> +       }
> +
> +       shift = ffs(data[1]) - 1;
> +       width = fls(data[1]) - ffs(data[1]) + 1;
> +
> +       /* 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);
> +
> +       clk = clk_register_divider_table(NULL, clk_name, parent_names[0],
> +                                        CLK_IS_BASIC, hs_clk.sctrl + data[0],
> +                                        shift, width, 0,
> +                                        table, &hs_clk.lock);
> +       if (IS_ERR(clk))
> +               goto err_par;
> +       of_clk_add_provider(np, of_clk_src_simple_get, clk);
> +       return;
> +err_par:
> +       kfree(parent_names);
> +err:
> +       kfree(table);
> +}
> +
> +static const __initconst struct of_device_id hs_clk_match[] = {
> +       {
> +               .compatible = "fixed-clock",
> +               .data = of_fixed_clk_setup,
> +       }, {
> +               .compatible = "hisilicon,hi3620-clk-mux",
> +               .data = hi3620_clkmux_setup,
> +       }, {
> +               .compatible = "hisilicon,hi3620-clk-gate",
> +               .data = hi3620_clkgate_setup,
> +       }, {
> +               .compatible = "hisilicon,clk-gate",
> +               .data = hs_clkgate_setup,
> +       }, {
> +               .compatible = "hisilicon,clk-div-table",
> +               .data = hs_divider_clk_setup,
> +       }, {
> +               .compatible = "hisilicon,clk-fixed-factor",
> +               .data = hs_fixed_factor_clk_setup,
> +       },
> +};
> +
> +void __init hs_init_clocks(void)
> +{
> +       struct device_node *node;
> +
> +       /*map pmctrl registers*/
> +       node = of_find_compatible_node(NULL, NULL, "hisilicon,pmctrl");
> +       hs_clk.pmctrl = of_iomap(node, 0);
> +       WARN_ON(!hs_clk.pmctrl);
> +
> +       node = of_find_compatible_node(NULL, NULL, "hisilicon,sctrl");
> +       hs_clk.sctrl = of_iomap(node, 0);
> +
> +       of_clk_init(hs_clk_match);
> +}
> --
> 1.7.10.4
>

Forget to loop Mike.

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28 11:04   ` Arnd Bergmann
@ 2013-02-28 12:55     ` Haojian Zhuang
  2013-02-28 14:17       ` Arnd Bergmann
  0 siblings, 1 reply; 13+ messages in thread
From: Haojian Zhuang @ 2013-02-28 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 February 2013 19:04, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 28 February 2013, Haojian Zhuang wrote:
>> Add board support with device tree for Hisilicon Hi36xx/Hi37xx platform.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> Ah, nice and small ;-)
>
>>  arch/arm/Kconfig          |    2 ++
>>  arch/arm/Makefile         |    1 +
>>  arch/arm/mach-hs/Kconfig  |   23 +++++++++++++
>>  arch/arm/mach-hs/Makefile |    5 +++
>>  arch/arm/mach-hs/hs-dt.c  |   83 +++++++++++++++++++++++++++++++++++++++++++++
>
> Regarding the naming, I wonder if "hs" is unique enough for a platform name.
> AFAIK, HiSilicon has a couple of independently developed SoC families,
> so we might want to be a bit more specific here, e.g. mach-hi3xxx.
>
> Regarding the file name, I think the "-dt" postfix is redundant, when we
> only support booting using DT. I would call this one the same thing as the
> platform name, whichever we go with.
>
OK

>> +config MACH_HS_DT
>> +     bool "Hisilicon Development Board"
>> +     default y
>> +     help
>> +       Say 'Y' here if you want to support the Hisilicon Development
>> +       Board.
>> +
>> +endif
>
> I don't think we need this option. Let's just always build the file
> when the platform is enabled, and build all .dtb files as well.
>
OK

>> +static struct clk_lookup sp804_lookup = {
>> +     .dev_id = "sp804",
>> +     .clk    = NULL,
>> +};
>
> (adding Mike to Cc)
>
> Shouldn't the clk_lookup be automatic with a fully DT enabled platform now?
>
>> +extern void __init hs_init_clocks(void);
>> +static void __init hs_timer_init(void)
>> +{
>> +     struct device_node *node = NULL;
>> +     void __iomem *base;
>> +     int irq;
>> +
>> +     hs_init_clocks();
>> +
>> +     node = of_find_matching_node(NULL, hs_timer_match);
>> +     WARN_ON(!node);
>> +     if (!node) {
>> +             pr_err("Failed to find sp804 timer\n");
>> +             return;
>> +     }
>> +     base = of_iomap(node, 0);
>> +     WARN_ON(!base);
>> +
>> +     /* timer0 is used as clock event, and timer1 is clock source. */
>> +     irq = irq_of_parse_and_map(node, 0);
>> +     WARN_ON(!irq);
>> +
>> +     sp804_lookup.clk = of_clk_get(node, 0);
>> +     clkdev_add(&sp804_lookup);
>> +
>> +     sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, "timer1");
>> +     sp804_clockevents_init(base, irq, "timer0");
>> +}
>
> I think for the clocksource/clockevents driver, we should move
> arch/arm/common/timer-sp.c to drivers/clocksource now and integrate
> it into the automatic probing through clocksource_of_init().
>
Sounds good.

>> +static void __init hs_init(void)
>> +{
>> +     of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>> +}
>> +
>> +static const char *hs_compat[] __initdata = {
>> +     "hisilicon,hi3620-hi4511",
>> +     NULL,
>> +};
>> +
>> +DT_MACHINE_START(HS_DT, "Hisilicon Hi36xx/Hi37xx (Flattened Device Tree)")
>> +     /* Maintainer: Haojian Zhuang <haojian.zhuang@linaro.org> */
>> +     .map_io         = debug_ll_io_init,
>> +     .init_irq       = irqchip_init,
>> +     .init_time      = hs_timer_init,
>> +     .init_machine   = hs_init,
>> +     .dt_compat      = hs_compat,
>> +MACHINE_END
>
> This looks right at the moment, but I also have a patch to make it possible to drop the
> irqchip_init, clocksource_of_init and hs_init() calls here, as they are all the
> defaults. At that point, the platform would be essentially empty except for the
> debug_ll_io_init part that is inherently platform specific.
>
>         Arnd

Could you give me the link of your patch? I could rebase this patch.

Regards
Haojian

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28 12:55     ` Haojian Zhuang
@ 2013-02-28 14:17       ` Arnd Bergmann
  0 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2013-02-28 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 28 February 2013, Haojian Zhuang wrote:
> >
> > This looks right at the moment, but I also have a patch to make it possible to drop the
> > irqchip_init, clocksource_of_init and hs_init() calls here, as they are all the
> > defaults. At that point, the platform would be essentially empty except for the
> > debug_ll_io_init part that is inherently platform specific.
> >
> >         Arnd
> 
> Could you give me the link of your patch? I could rebase this patch.

I only posted an RFC so far, at

https://patchwork.kernel.org/patch/2074871/

It's probably easier for now if you ignore it. We will see how to stage
things after the merge window, once we are putting both your patch and
mine into arm-soc.

	Arnd

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28  7:19 ` [PATCH 3/7] ARM: hs: add board support with device tree Haojian Zhuang
  2013-02-28 11:04   ` Arnd Bergmann
@ 2013-02-28 21:46   ` Michal Simek
  2013-03-01 11:45     ` Arnd Bergmann
  1 sibling, 1 reply; 13+ messages in thread
From: Michal Simek @ 2013-02-28 21:46 UTC (permalink / raw)
  To: linux-arm-kernel

2013/2/27 Haojian Zhuang <haojian.zhuang@linaro.org>:
> Add board support with device tree for Hisilicon Hi36xx/Hi37xx platform.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  arch/arm/Kconfig          |    2 ++
>  arch/arm/Makefile         |    1 +
>  arch/arm/mach-hs/Kconfig  |   23 +++++++++++++
>  arch/arm/mach-hs/Makefile |    5 +++
>  arch/arm/mach-hs/hs-dt.c  |   83 +++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 114 insertions(+)
>  create mode 100644 arch/arm/mach-hs/Kconfig
>  create mode 100644 arch/arm/mach-hs/Makefile
>  create mode 100644 arch/arm/mach-hs/hs-dt.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index dedf02b..dfe70aa 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1055,6 +1055,8 @@ source "arch/arm/mach-h720x/Kconfig"
>
>  source "arch/arm/mach-highbank/Kconfig"
>
> +source "arch/arm/mach-hs/Kconfig"
> +
>  source "arch/arm/mach-integrator/Kconfig"
>
>  source "arch/arm/mach-iop32x/Kconfig"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index ee4605f..08a913b 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -149,6 +149,7 @@ machine-$(CONFIG_ARCH_EP93XX)               += ep93xx
>  machine-$(CONFIG_ARCH_GEMINI)          += gemini
>  machine-$(CONFIG_ARCH_H720X)           += h720x
>  machine-$(CONFIG_ARCH_HIGHBANK)                += highbank
> +machine-$(CONFIG_ARCH_HS)              += hs
>  machine-$(CONFIG_ARCH_INTEGRATOR)      += integrator
>  machine-$(CONFIG_ARCH_IOP13XX)         += iop13xx
>  machine-$(CONFIG_ARCH_IOP32X)          += iop32x
> diff --git a/arch/arm/mach-hs/Kconfig b/arch/arm/mach-hs/Kconfig
> new file mode 100644
> index 0000000..491c6da
> --- /dev/null
> +++ b/arch/arm/mach-hs/Kconfig
> @@ -0,0 +1,23 @@
> +config ARCH_HS
> +       bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7
> +       select ARM_AMBA
> +       select ARM_GIC
> +       select CACHE_L2X0
> +       select CACHE_PL310
> +       select PINCTRL
> +       select PINCTRL_SINGLE
> +       select SERIAL_AMBA_PL011
> +       select SERIAL_AMBA_PL011_CONSOLE
> +       help
> +         Support for Hisilicon Hi36xx/Hi37xx processor family
> +
> +if ARCH_HS
> +
> +config MACH_HS_DT
> +       bool "Hisilicon Development Board"
> +       default y
> +       help
> +         Say 'Y' here if you want to support the Hisilicon Development
> +         Board.
> +
> +endif
> diff --git a/arch/arm/mach-hs/Makefile b/arch/arm/mach-hs/Makefile
> new file mode 100644
> index 0000000..d79ecb5
> --- /dev/null
> +++ b/arch/arm/mach-hs/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Makefile for Hisilicon Hi36xx/Hi37xx processors line
> +#
> +
> +obj-$(CONFIG_MACH_HS_DT)       += hs-dt.o
> diff --git a/arch/arm/mach-hs/hs-dt.c b/arch/arm/mach-hs/hs-dt.c
> new file mode 100644
> index 0000000..813ebb0
> --- /dev/null
> +++ b/arch/arm/mach-hs/hs-dt.c
> @@ -0,0 +1,83 @@
> +/*
> + * (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.h>
> +#include <linux/clkdev.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/hardware/arm_timer.h>
> +#include <asm/hardware/timer-sp.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <asm/mach/time.h>
> +
> +static struct of_device_id hs_timer_match[] __initdata = {
> +       { .compatible = "arm,sp804", },
> +       {}
> +};
> +
> +static struct clk_lookup sp804_lookup = {
> +       .dev_id = "sp804",
> +       .clk    = NULL,
> +};
> +
> +extern void __init hs_init_clocks(void);

this shouldn't be in this file. Run checkpatch.pl on it.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform

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

* [PATCH 3/7] ARM: hs: add board support with device tree
  2013-02-28 21:46   ` Michal Simek
@ 2013-03-01 11:45     ` Arnd Bergmann
  0 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2013-03-01 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 28 February 2013, Michal Simek wrote:
> > +
> > +extern void __init hs_init_clocks(void);
> 
> this shouldn't be in this file. Run checkpatch.pl on it.

Right, I believe that the new CLK_OF_DECLARE macro should
take care of this. For now, you still need to call
"of_clk_init(NULL);" from platform code when using this,
but I suppose we will find a way to mvoe that into common
arch code eventually.

	Arnd

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

end of thread, other threads:[~2013-03-01 11:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-28  7:19 [PATCH 1/7] ARM: debug: support debug ll on hisilicon soc Haojian Zhuang
2013-02-28  7:19 ` [PATCH 2/7] clk: hs: add clock support Haojian Zhuang
2013-02-28 12:48   ` Haojian Zhuang
2013-02-28  7:19 ` [PATCH 3/7] ARM: hs: add board support with device tree Haojian Zhuang
2013-02-28 11:04   ` Arnd Bergmann
2013-02-28 12:55     ` Haojian Zhuang
2013-02-28 14:17       ` Arnd Bergmann
2013-02-28 21:46   ` Michal Simek
2013-03-01 11:45     ` Arnd Bergmann
2013-02-28  7:19 ` [PATCH 4/7] ARM: hs: enable hi4511 " Haojian Zhuang
2013-02-28  7:19 ` [PATCH 5/7] document: append hisilicon clock binding Haojian Zhuang
2013-02-28  7:19 ` [PATCH 6/7] Document: dts: create hisilicon document Haojian Zhuang
2013-02-28  7:19 ` [PATCH 7/7] ARM: config: append arch hs into multi defconfig Haojian Zhuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).