Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 11/12] ARM: imx: correct i.mx6sll dram io low power mode
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

i.MX6SLL has different DRAM IO offset, and it has no
CAS/RAS/ODT/RESET pin now, correct the DRAM IO offset.

To better support all different i.MX6 SoCs and different
DRAM types, introduce a new column to store the low power
settings for DRAM IO, then suspend asm code no need to check
SoC or DRAM type, just get the DRAM IO's low power
settings from OCRAM pm_info and set to each DRAM IO.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/mach-imx/pm-imx6.c      | 17 ++++++++++++++++-
 arch/arm/mach-imx/suspend-imx6.S | 29 +++++++----------------------
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 2ed4316..5fb78a9 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -230,7 +230,7 @@ struct imx6_cpu_pm_info {
 	struct imx6_pm_base gpc_base;
 	struct imx6_pm_base l2_base;
 	u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
-	u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+	u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][3]; /* To save offset,value and low power setting */
 } __aligned(8);
 
 void imx6_set_int_mem_clk_lpm(bool enable)
@@ -570,6 +570,21 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 		pm_info->mmdc_io_val[i][1] =
 			readl_relaxed(pm_info->iomuxc_base.vbase +
 			mmdc_offset_array[i]);
+		pm_info->mmdc_io_val[i][2] = 0;
+
+	}
+
+	/* i.MX6SLL has no DRAM RESET pin */
+	if (cpu_is_imx6sll()) {
+		pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+		pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x1000;
+	} else {
+		if (pm_info->ddr_type == IMX_DDR_TYPE_LPDDR2) {
+			 /* for LPDDR2, CKE0/1 and RESET pin need special setting */
+			pm_info->mmdc_io_val[pm_info->mmdc_io_num - 3][2] = 0x1000;
+			pm_info->mmdc_io_val[pm_info->mmdc_io_num - 2][2] = 0x1000;
+			pm_info->mmdc_io_val[pm_info->mmdc_io_num - 1][2] = 0x80000;
+		}
 	}
 
 	imx6_suspend_in_ocram_fn = fncpy(
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index 76ee2ce..c9a26f4 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -104,7 +104,7 @@
 	add	r7, r7, r0
 1:
 	ldr	r8, [r7], #0x4
-	ldr	r9, [r7], #0x4
+	ldr	r9, [r7], #0x8
 	str	r9, [r11, r8]
 	subs	r6, r6, #0x1
 	bne	1b
@@ -179,7 +179,6 @@ ENTRY(imx6_suspend)
 	ldr	r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
 	ldr	r6, [r11, #0x0]
 
-	/* use r11 to store the IO address */
 	ldr	r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
 	/* store physical resume addr and pm_info address. */
 	str	r9, [r11, #MX6Q_SRC_GPR1]
@@ -207,32 +206,18 @@ poll_dvfs_set:
 	ands	r7, r7, #(1 << 25)
 	beq	poll_dvfs_set
 
+	/* use r11 to store the IO address */
 	ldr	r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
-	ldr	r6, =0x0
-	ldr	r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+	ldr	r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
 	ldr	r8, =PM_INFO_MMDC_IO_VAL_OFFSET
 	add	r8, r8, r0
-	/* LPDDR2's last 3 IOs need special setting */
-	cmp	r3, #IMX_DDR_TYPE_LPDDR2
-	subeq	r7, r7, #0x3
 set_mmdc_io_lpm:
-	ldr	r9, [r8], #0x8
-	str	r6, [r11, r9]
-	subs	r7, r7, #0x1
+	ldr	r7, [r8], #0x8
+	ldr	r9, [r8], #0x4
+	str	r9, [r11, r7]
+	subs	r6, r6, #0x1
 	bne	set_mmdc_io_lpm
 
-	cmp 	r3, #IMX_DDR_TYPE_LPDDR2
-	bne	set_mmdc_io_lpm_done
-	ldr	r6, =0x1000
-	ldr	r9, [r8], #0x8
-	str	r6, [r11, r9]
-	ldr	r9, [r8], #0x8
-	str	r6, [r11, r9]
-	ldr	r6, =0x80000
-	ldr	r9, [r8]
-	str	r6, [r11, r9]
-set_mmdc_io_lpm_done:
-
 	/*
 	 * mask all GPC interrupts before
 	 * enabling the RBC counters to
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 10/12] ARM: imx: Add suspend/resume support for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add suspend/resume support for imx6sll.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/mach-imx/pm-imx6.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 1515e49..2ed4316 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -145,6 +145,13 @@ struct imx6_pm_socdata {
 	0x494, 0x4b0,	            /* MODE_CTL, MODE, */
 };
 
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+	0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
+	0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+	0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
+	0x2a4, 0x2a8,		    /* SDCKE0, SDCKE1*/
+};
+
 static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
 	.mmdc_compat = "fsl,imx6q-mmdc",
 	.src_compat = "fsl,imx6q-src",
@@ -195,6 +202,15 @@ struct imx6_pm_socdata {
 	.mmdc_io_offset = imx6ul_mmdc_io_offset,
 };
 
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+	.mmdc_compat = "fsl,imx6sll-mmdc",
+	.src_compat = "fsl,imx6sll-src",
+	.iomuxc_compat = "fsl,imx6sll-iomuxc",
+	.gpc_compat = "fsl,imx6sll-gpc",
+	.pl310_compat = "arm,pl310-cache",
+	.mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+	.mmdc_io_offset = imx6sll_mmdc_io_offset,
+};
 /*
  * This structure is for passing necessary data for low level ocram
  * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
@@ -293,9 +309,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 		val |= 0x2 << BP_CLPCR_LPM;
 		val &= ~BM_CLPCR_VSTBY;
 		val &= ~BM_CLPCR_SBYOS;
-		if (cpu_is_imx6sl())
+		if (cpu_is_imx6sl() || cpu_is_imx6sll())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
-		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+			cpu_is_imx6sll())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -310,9 +327,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 		val |= 0x3 << BP_CLPCR_STBY_COUNT;
 		val |= BM_CLPCR_VSTBY;
 		val |= BM_CLPCR_SBYOS;
-		if (cpu_is_imx6sl() || cpu_is_imx6sx())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
-		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx() ||
+		    cpu_is_imx6ul() || cpu_is_imx6sll())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -373,6 +391,7 @@ static int imx6q_pm_enter(suspend_state_t state)
 			imx6sl_set_wait_clk(true);
 		/* Zzz ... */
 		cpu_do_idle();
+
 		if (cpu_is_imx6sl())
 			imx6sl_set_wait_clk(false);
 		imx_gpc_post_resume();
@@ -632,7 +651,10 @@ void __init imx6dl_pm_init(void)
 
 void __init imx6sl_pm_init(void)
 {
-	imx6_pm_common_init(&imx6sl_pm_data);
+	if (cpu_is_imx6sl())
+		imx6_pm_common_init(&imx6sl_pm_data);
+	else
+		imx6_pm_common_init(&imx6sll_pm_data);
 }
 
 void __init imx6sx_pm_init(void)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 09/12] ARM: debug: Add low level debug support for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add low level debug support for i.MX6SLL.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/Kconfig.debug            |  9 +++++++++
 arch/arm/include/debug/imx-uart.h | 10 ++++++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 408540f..d52d48c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -405,6 +405,13 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX6SL.
 
+	config DEBUG_IMX6SLL_UART
+		bool "i.MX6SLL Debug UART"
+		depends on SOC_IMX6SLL
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on i.MX6SLL.
+
 	config DEBUG_IMX6SX_UART
 		bool "i.MX6SX Debug UART"
 		depends on SOC_IMX6SX
@@ -1374,6 +1381,7 @@ config DEBUG_IMX_UART_PORT
 						DEBUG_IMX53_UART || \
 						DEBUG_IMX6Q_UART || \
 						DEBUG_IMX6SL_UART || \
+						DEBUG_IMX6SLL_UART || \
 						DEBUG_IMX6SX_UART || \
 						DEBUG_IMX6UL_UART || \
 						DEBUG_IMX7D_UART
@@ -1428,6 +1436,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_IMX53_UART ||\
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
+				 DEBUG_IMX6SLL_UART || \
 				 DEBUG_IMX6SX_UART || \
 				 DEBUG_IMX6UL_UART || \
 				 DEBUG_IMX7D_UART
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e9..24e60ce 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -81,6 +81,14 @@
 #define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
 #define IMX6SL_UART_BASE(n)	IMX6SL_UART_BASE_ADDR(n)
 
+#define IMX6SLL_UART1_BASE_ADDR 0x02020000
+#define IMX6SLL_UART2_BASE_ADDR 0x02024000
+#define IMX6SLL_UART3_BASE_ADDR 0x02034000
+#define IMX6SLL_UART4_BASE_ADDR 0x02018000
+#define IMX6SLL_UART5_BASE_ADDR 0x021f4000
+#define IMX6SLL_UART_BASE_ADDR(n) IMX6SLL_UART##n##_BASE_ADDR
+#define IMX6SLL_UART_BASE(n)	IMX6SLL_UART_BASE_ADDR(n)
+
 #define IMX6SX_UART1_BASE_ADDR	0x02020000
 #define IMX6SX_UART2_BASE_ADDR	0x021e8000
 #define IMX6SX_UART3_BASE_ADDR	0x021ec000
@@ -133,6 +141,8 @@
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6Q)
 #elif defined(CONFIG_DEBUG_IMX6SL_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6SL)
+#elif defined(CONFIG_DEBUG_IMX6SLL_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6SLL)
 #elif defined(CONFIG_DEBUG_IMX6SX_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6SX)
 #elif defined(CONFIG_DEBUG_IMX6UL_UART)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 08/12] ARM: dts: imx: Add imx6sll EVK board dts support
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add basic dts support for imx6sll EVK board.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/boot/dts/Makefile        |   2 +
 arch/arm/boot/dts/imx6sll-evk.dts | 474 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 476 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6sll-evk.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 38c595d..24eb4bd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -416,6 +416,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 dtb-$(CONFIG_SOC_IMX6SL) += \
 	imx6sl-evk.dtb \
 	imx6sl-warp.dtb
+dtb-$(CONFIG_SOC_IMX6SLL) += \
+	imx6sll-evk.dtb
 dtb-$(CONFIG_SOC_IMX6SX) += \
 	imx6sx-nitrogen6sx.dtb \
 	imx6sx-sabreauto.dtb \
diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts
new file mode 100644
index 0000000..7b8264b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sll-evk.dts
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sll.dtsi"
+
+/ {
+	model = "Freescale i.MX6SLL EVK Board";
+	compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
+
+	memory {
+		reg = <0x80000000 0x80000000>;
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		status = "okay";
+	};
+
+	reg_usb_otg1_vbus: reg-usb-otg1-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg1_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_usb_otg2_vbus: reg-usb-otg2-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg2_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_aud3v: reg-aud3v {
+		compatible = "regulator-fixed";
+		regulator-name = "wm8962-supply-3v15";
+		regulator-min-microvolt = <3150000>;
+		regulator-max-microvolt = <3150000>;
+		regulator-boot-on;
+	};
+
+	reg_aud4v: reg-aud4v {
+		compatible = "regulator-fixed";
+		regulator-name = "wm8962-supply-4v2";
+		regulator-min-microvolt = <4325000>;
+		regulator-max-microvolt = <4325000>;
+		regulator-boot-on;
+	};
+
+	reg_lcd: reg-lcd {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd-pwr";
+		gpio = <&gpio4 8 0>;
+		enable-active-high;
+	};
+
+	reg_sd1_vmmc: reg-sd1-vmmc {
+		compatible = "regulator-fixed";
+		regulator-name = "SD1_SPWR";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+		gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&cpu0 {
+	arm-supply = <&sw1a_reg>;
+	soc-supply = <&sw1c_reg>;
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	pmic: pfuze100 at 08 {
+		compatible = "fsl,pfuze100";
+		reg = <0x08>;
+
+		regulators {
+			sw1a_reg: sw1ab {
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw1c_reg: sw1c {
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw2_reg: sw2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3a_reg: sw3a {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3b_reg: sw3b {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw4_reg: sw4 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			swbst_reg: swbst {
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+			};
+
+			snvs_reg: vsnvs {
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr {
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+				regulator-always-on;
+			};
+
+			vgen2_reg: vgen2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen3_reg: vgen3 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vgen4_reg: vgen4 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen6_reg: vgen6 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	pinctrl_hog: hoggrp {
+		fsl,pins = <
+			MX6SLL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
+			MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22 0x17059
+			MX6SLL_PAD_KEY_COL3__GPIO3_IO30	0x17059
+			/*
+			 * Must set the LVE of pad SD2_RESET, otherwise current
+			 * leakage through eMMC chip will pull high the VCCQ to
+			 * 2.6v, which will impact SD1 and SD3 SD3.0 voltage switch.
+			 */
+			MX6SLL_PAD_SD2_RESET__GPIO4_IO27 0x417059
+			MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x17059
+			MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059 /* SD3 CD */
+			MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059 /*SD3 RESET */
+			MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x17059
+			MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* HP DETECT */
+			/* CHG_FLT, CHG_UOK/DOK, CHG_STATUS */
+			MX6SLL_PAD_ECSPI2_MISO__GPIO4_IO14 0x17000
+			MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x17000
+			MX6SLL_PAD_ECSPI2_SS0__GPIO4_IO15  0x17000
+		>;
+	};
+
+	pinctrl_audmux3: audmux3grp {
+		fsl,pins = <
+			MX6SLL_PAD_AUD_TXC__AUD3_TXC		0x4130b0
+			MX6SLL_PAD_AUD_TXFS__AUD3_TXFS		0x4130b0
+			MX6SLL_PAD_AUD_TXD__AUD3_TXD		0x4110b0
+			MX6SLL_PAD_AUD_RXD__AUD3_RXD		0x4130b0
+			MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT	0x4130b0
+		>;
+	};
+
+	pinctrl_csi1: csi1grp {
+		fsl,pins = <
+			MX6SLL_PAD_EPDC_GDRL__CSI_MCLK		0x1b088
+			MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK	0x1b088
+			MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC		0x1b088
+			MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC		0x1b088
+			MX6SLL_PAD_EPDC_DATA02__CSI_DATA02	0x1b088
+			MX6SLL_PAD_EPDC_DATA03__CSI_DATA03	0x1b088
+			MX6SLL_PAD_EPDC_DATA04__CSI_DATA04	0x1b088
+			MX6SLL_PAD_EPDC_DATA05__CSI_DATA05	0x1b088
+			MX6SLL_PAD_EPDC_DATA06__CSI_DATA06	0x1b088
+			MX6SLL_PAD_EPDC_DATA07__CSI_DATA07	0x1b088
+			MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08	0x1b088
+			MX6SLL_PAD_EPDC_SDLE__CSI_DATA09	0x1b088
+			MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26	0x80000000
+			MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25	0x80000000
+		>;
+	};
+
+	pinctrl_lcdif_dat: lcdifdatgrp {
+		fsl,pins = <
+			MX6SLL_PAD_LCD_DATA00__LCD_DATA00	0x79
+			MX6SLL_PAD_LCD_DATA01__LCD_DATA01	0x79
+			MX6SLL_PAD_LCD_DATA02__LCD_DATA02	0x79
+			MX6SLL_PAD_LCD_DATA03__LCD_DATA03	0x79
+			MX6SLL_PAD_LCD_DATA04__LCD_DATA04	0x79
+			MX6SLL_PAD_LCD_DATA05__LCD_DATA05	0x79
+			MX6SLL_PAD_LCD_DATA06__LCD_DATA06	0x79
+			MX6SLL_PAD_LCD_DATA07__LCD_DATA07	0x79
+			MX6SLL_PAD_LCD_DATA08__LCD_DATA08	0x79
+			MX6SLL_PAD_LCD_DATA09__LCD_DATA09	0x79
+			MX6SLL_PAD_LCD_DATA10__LCD_DATA10	0x79
+			MX6SLL_PAD_LCD_DATA11__LCD_DATA11	0x79
+			MX6SLL_PAD_LCD_DATA12__LCD_DATA12	0x79
+			MX6SLL_PAD_LCD_DATA13__LCD_DATA13	0x79
+			MX6SLL_PAD_LCD_DATA14__LCD_DATA14	0x79
+			MX6SLL_PAD_LCD_DATA15__LCD_DATA15	0x79
+			MX6SLL_PAD_LCD_DATA16__LCD_DATA16	0x79
+			MX6SLL_PAD_LCD_DATA17__LCD_DATA17	0x79
+			MX6SLL_PAD_LCD_DATA18__LCD_DATA18	0x79
+			MX6SLL_PAD_LCD_DATA19__LCD_DATA19	0x79
+			MX6SLL_PAD_LCD_DATA20__LCD_DATA20	0x79
+			MX6SLL_PAD_LCD_DATA21__LCD_DATA21	0x79
+			MX6SLL_PAD_LCD_DATA22__LCD_DATA22	0x79
+			MX6SLL_PAD_LCD_DATA23__LCD_DATA23	0x79
+		>;
+	};
+
+	pinctrl_lcdif_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6SLL_PAD_LCD_CLK__LCD_CLK		0x79
+			MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE	0x79
+			MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC		0x79
+			MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC		0x79
+			MX6SLL_PAD_LCD_RESET__LCD_RESET		0x79
+			MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08	0x79
+		>;
+	};
+
+	pinctrl_max17135: max17135grp-1 {
+		fsl,pins = <
+			MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13	0x80000000  /* pwrgood */
+			MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03	0x80000000  /* vcom_ctrl */
+			MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14	0x80000000  /* wakeup */
+			MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07	0x80000000  /* v3p3 */
+			MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12	0x80000000  /* pwr int */
+		>;
+	};
+
+	pinctrl_spdif: spdifgrp {
+		fsl,pins = <
+			MX6SLL_PAD_SD2_DATA4__SPDIF_OUT 0x4130b0
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+			MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6SLL_PAD_SD1_CMD__SD1_CMD	0x17059
+			MX6SLL_PAD_SD1_CLK__SD1_CLK	0x13059
+			MX6SLL_PAD_SD1_DATA0__SD1_DATA0	0x17059
+			MX6SLL_PAD_SD1_DATA1__SD1_DATA1	0x17059
+			MX6SLL_PAD_SD1_DATA2__SD1_DATA2	0x17059
+			MX6SLL_PAD_SD1_DATA3__SD1_DATA3	0x17059
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+		fsl,pins = <
+			MX6SLL_PAD_SD1_CMD__SD1_CMD	0x170b9
+			MX6SLL_PAD_SD1_CLK__SD1_CLK	0x130b9
+			MX6SLL_PAD_SD1_DATA0__SD1_DATA0	0x170b9
+			MX6SLL_PAD_SD1_DATA1__SD1_DATA1	0x170b9
+			MX6SLL_PAD_SD1_DATA2__SD1_DATA2	0x170b9
+			MX6SLL_PAD_SD1_DATA3__SD1_DATA3	0x170b9
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+		fsl,pins = <
+			MX6SLL_PAD_SD1_CMD__SD1_CMD	0x170f9
+			MX6SLL_PAD_SD1_CLK__SD1_CLK	0x130f9
+			MX6SLL_PAD_SD1_DATA0__SD1_DATA0	0x170f9
+			MX6SLL_PAD_SD1_DATA1__SD1_DATA1	0x170f9
+			MX6SLL_PAD_SD1_DATA2__SD1_DATA2	0x170f9
+			MX6SLL_PAD_SD1_DATA3__SD1_DATA3	0x170f9
+		>;
+	};
+
+	pinctrl_usbotg1: usbotg1grp {
+		fsl,pins = <
+			MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6SLL_PAD_I2C1_SCL__I2C1_SCL	 0x4001b8b1
+			MX6SLL_PAD_I2C1_SDA__I2C1_SDA	 0x4001b8b1
+		>;
+	};
+
+	pinctrl_pwm1: pmw1grp {
+		fsl,pins = <
+			MX6SLL_PAD_PWM1__PWM1_OUT   0x110b0
+		>;
+	};
+};
+
+&lcdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcdif_dat
+		     &pinctrl_lcdif_ctrl>;
+	lcd-supply = <&reg_lcd>;
+	display = <&display>;
+	status = "okay";
+
+	display: display {
+		bits-per-pixel = <16>;
+		bus-width = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: timing0 {
+				clock-frequency = <33500000>;
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <89>;
+				hfront-porch = <164>;
+				vback-porch = <23>;
+				vfront-porch = <10>;
+				hsync-len = <10>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+	keep-power-in-suspend;
+	enable-sdio-wakeup;
+	vmmc-supply = <&reg_sd1_vmmc>;
+	status = "okay";
+};
+
+&usbotg1 {
+	vbus-supply = <&reg_usb_otg1_vbus>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
+	disable-over-current;
+	srp-disable;
+	hnp-disable;
+	adp-disable;
+	status = "okay";
+};
+
+&usbotg2 {
+	vbus-supply = <&reg_usb_otg2_vbus>;
+	dr_mode = "host";
+	disable-over-current;
+	status = "okay";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 06/12] driver: pinctrl: imx: Add pinctrl driver support for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add pinctrl driver support for imx6sll.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/mach-imx/Kconfig                   |   1 +
 drivers/pinctrl/freescale/Kconfig           |   7 +
 drivers/pinctrl/freescale/Makefile          |   1 +
 drivers/pinctrl/freescale/pinctrl-imx6sll.c | 385 ++++++++++++++++++++++++++++
 4 files changed, 394 insertions(+)
 create mode 100644 drivers/pinctrl/freescale/pinctrl-imx6sll.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 33bcfda..c907d9f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -514,6 +514,7 @@ config SOC_IMX6SL
 
 config SOC_IMX6SLL
 	bool "i.MX6 SoloLiteLite support"
+	select PINCTRL_IMX6SLL
 	select SOC_IMX6
 
 	help
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig
index fc8cbf6..93ca39f 100644
--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig
@@ -81,6 +81,13 @@ config PINCTRL_IMX6SL
 	help
 	  Say Y here to enable the imx6sl pinctrl driver
 
+config PINCTRL_IMX6SLL
+	bool "IMX6SL pinctrl driver"
+	depends on SOC_IMX6SLL
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the imx6sl pinctrl driver
+
 config PINCTRL_IMX6SX
 	bool "IMX6SX pinctrl driver"
 	depends on SOC_IMX6SX
diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile
index d44c9e2..5f23765 100644
--- a/drivers/pinctrl/freescale/Makefile
+++ b/drivers/pinctrl/freescale/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_IMX53)	+= pinctrl-imx53.o
 obj-$(CONFIG_PINCTRL_IMX6Q)	+= pinctrl-imx6q.o
 obj-$(CONFIG_PINCTRL_IMX6Q)	+= pinctrl-imx6dl.o
 obj-$(CONFIG_PINCTRL_IMX6SL)	+= pinctrl-imx6sl.o
+obj-$(CONFIG_PINCTRL_IMX6SLL)	+= pinctrl-imx6sll.o
 obj-$(CONFIG_PINCTRL_IMX6SX)	+= pinctrl-imx6sx.o
 obj-$(CONFIG_PINCTRL_IMX6UL)	+= pinctrl-imx6ul.o
 obj-$(CONFIG_PINCTRL_IMX7D)	+= pinctrl-imx7d.o
diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sll.c b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
new file mode 100644
index 0000000..2f4baff
--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-imx6sll.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Author: Bai Ping <ping.bai@nxp.com>
+ * 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/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum imx6sll_pads {
+	MX6SLL_PAD_RESERVE0 = 0,
+	MX6SLL_PAD_RESERVE1 = 1,
+	MX6SLL_PAD_RESERVE2 = 2,
+	MX6SLL_PAD_RESERVE3 = 3,
+	MX6SLL_PAD_RESERVE4 = 4,
+	MX6SLL_PAD_WDOG_B = 5,
+	MX6SLL_PAD_REF_CLK_24M = 6,
+	MX6SLL_PAD_REF_CLK_32K = 7,
+	MX6SLL_PAD_PWM1 = 8,
+	MX6SLL_PAD_KEY_COL0 = 9,
+	MX6SLL_PAD_KEY_ROW0 = 10,
+	MX6SLL_PAD_KEY_COL1 = 11,
+	MX6SLL_PAD_KEY_ROW1 = 12,
+	MX6SLL_PAD_KEY_COL2 = 13,
+	MX6SLL_PAD_KEY_ROW2 = 14,
+	MX6SLL_PAD_KEY_COL3 = 15,
+	MX6SLL_PAD_KEY_ROW3 = 16,
+	MX6SLL_PAD_KEY_COL4 = 17,
+	MX6SLL_PAD_KEY_ROW4 = 18,
+	MX6SLL_PAD_KEY_COL5 = 19,
+	MX6SLL_PAD_KEY_ROW5 = 20,
+	MX6SLL_PAD_KEY_COL6 = 21,
+	MX6SLL_PAD_KEY_ROW6 = 22,
+	MX6SLL_PAD_KEY_COL7 = 23,
+	MX6SLL_PAD_KEY_ROW7 = 24,
+	MX6SLL_PAD_EPDC_DATA00 = 25,
+	MX6SLL_PAD_EPDC_DATA01 = 26,
+	MX6SLL_PAD_EPDC_DATA02 = 27,
+	MX6SLL_PAD_EPDC_DATA03 = 28,
+	MX6SLL_PAD_EPDC_DATA04 = 29,
+	MX6SLL_PAD_EPDC_DATA05 = 30,
+	MX6SLL_PAD_EPDC_DATA06 = 31,
+	MX6SLL_PAD_EPDC_DATA07 = 32,
+	MX6SLL_PAD_EPDC_DATA08 = 33,
+	MX6SLL_PAD_EPDC_DATA09 = 34,
+	MX6SLL_PAD_EPDC_DATA10 = 35,
+	MX6SLL_PAD_EPDC_DATA11 = 36,
+	MX6SLL_PAD_EPDC_DATA12 = 37,
+	MX6SLL_PAD_EPDC_DATA13 = 38,
+	MX6SLL_PAD_EPDC_DATA14 = 39,
+	MX6SLL_PAD_EPDC_DATA15 = 40,
+	MX6SLL_PAD_EPDC_SDCLK = 41,
+	MX6SLL_PAD_EPDC_SDLE = 42,
+	MX6SLL_PAD_EPDC_SDOE = 43,
+	MX6SLL_PAD_EPDC_SDSHR = 44,
+	MX6SLL_PAD_EPDC_SDCE0 = 45,
+	MX6SLL_PAD_EPDC_SDCE1 = 46,
+	MX6SLL_PAD_EPDC_SDCE2 = 47,
+	MX6SLL_PAD_EPDC_SDCE3 = 48,
+	MX6SLL_PAD_EPDC_GDCLK = 49,
+	MX6SLL_PAD_EPDC_GDOE = 50,
+	MX6SLL_PAD_EPDC_GDRL = 51,
+	MX6SLL_PAD_EPDC_GDSP = 52,
+	MX6SLL_PAD_EPDC_VCOM0 = 53,
+	MX6SLL_PAD_EPDC_VCOM1 = 54,
+	MX6SLL_PAD_EPDC_BDR0 = 55,
+	MX6SLL_PAD_EPDC_BDR1 = 56,
+	MX6SLL_PAD_EPDC_PWR_CTRL0 = 57,
+	MX6SLL_PAD_EPDC_PWR_CTRL1 = 58,
+	MX6SLL_PAD_EPDC_PWR_CTRL2 = 59,
+	MX6SLL_PAD_EPDC_PWR_CTRL3 = 60,
+	MX6SLL_PAD_EPDC_PWR_COM = 61,
+	MX6SLL_PAD_EPDC_PWR_INT = 62,
+	MX6SLL_PAD_EPDC_PWR_STAT = 63,
+	MX6SLL_PAD_EPDC_PWR_WAKE = 64,
+	MX6SLL_PAD_LCD_CLK = 65,
+	MX6SLL_PAD_LCD_ENABLE = 66,
+	MX6SLL_PAD_LCD_HSYNC = 67,
+	MX6SLL_PAD_LCD_VSYNC = 68,
+	MX6SLL_PAD_LCD_RESET = 69,
+	MX6SLL_PAD_LCD_DATA00 = 70,
+	MX6SLL_PAD_LCD_DATA01 = 71,
+	MX6SLL_PAD_LCD_DATA02 = 72,
+	MX6SLL_PAD_LCD_DATA03 = 73,
+	MX6SLL_PAD_LCD_DATA04 = 74,
+	MX6SLL_PAD_LCD_DATA05 = 75,
+	MX6SLL_PAD_LCD_DATA06 = 76,
+	MX6SLL_PAD_LCD_DATA07 = 77,
+	MX6SLL_PAD_LCD_DATA08 = 78,
+	MX6SLL_PAD_LCD_DATA09 = 79,
+	MX6SLL_PAD_LCD_DATA10 = 80,
+	MX6SLL_PAD_LCD_DATA11 = 81,
+	MX6SLL_PAD_LCD_DATA12 = 82,
+	MX6SLL_PAD_LCD_DATA13 = 83,
+	MX6SLL_PAD_LCD_DATA14 = 84,
+	MX6SLL_PAD_LCD_DATA15 = 85,
+	MX6SLL_PAD_LCD_DATA16 = 86,
+	MX6SLL_PAD_LCD_DATA17 = 87,
+	MX6SLL_PAD_LCD_DATA18 = 88,
+	MX6SLL_PAD_LCD_DATA19 = 89,
+	MX6SLL_PAD_LCD_DATA20 = 90,
+	MX6SLL_PAD_LCD_DATA21 = 91,
+	MX6SLL_PAD_LCD_DATA22 = 92,
+	MX6SLL_PAD_LCD_DATA23 = 93,
+	MX6SLL_PAD_AUD_RXFS = 94,
+	MX6SLL_PAD_AUD_RXC = 95,
+	MX6SLL_PAD_AUD_RXD = 96,
+	MX6SLL_PAD_AUD_TXC = 97,
+	MX6SLL_PAD_AUD_TXFS = 98,
+	MX6SLL_PAD_AUD_TXD = 99,
+	MX6SLL_PAD_AUD_MCLK = 100,
+	MX6SLL_PAD_UART1_RXD = 101,
+	MX6SLL_PAD_UART1_TXD = 102,
+	MX6SLL_PAD_I2C1_SCL = 103,
+	MX6SLL_PAD_I2C1_SDA = 104,
+	MX6SLL_PAD_I2C2_SCL = 105,
+	MX6SLL_PAD_I2C2_SDA = 106,
+	MX6SLL_PAD_ECSPI1_SCLK = 107,
+	MX6SLL_PAD_ECSPI1_MOSI = 108,
+	MX6SLL_PAD_ECSPI1_MISO = 109,
+	MX6SLL_PAD_ECSPI1_SS0 = 110,
+	MX6SLL_PAD_ECSPI2_SCLK = 111,
+	MX6SLL_PAD_ECSPI2_MOSI = 112,
+	MX6SLL_PAD_ECSPI2_MISO = 113,
+	MX6SLL_PAD_ECSPI2_SS0 = 114,
+	MX6SLL_PAD_SD1_CLK = 115,
+	MX6SLL_PAD_SD1_CMD = 116,
+	MX6SLL_PAD_SD1_DATA0 = 117,
+	MX6SLL_PAD_SD1_DATA1 = 118,
+	MX6SLL_PAD_SD1_DATA2 = 119,
+	MX6SLL_PAD_SD1_DATA3 = 120,
+	MX6SLL_PAD_SD1_DATA4 = 121,
+	MX6SLL_PAD_SD1_DATA5 = 122,
+	MX6SLL_PAD_SD1_DATA6 = 123,
+	MX6SLL_PAD_SD1_DATA7 = 124,
+	MX6SLL_PAD_SD2_RESET = 125,
+	MX6SLL_PAD_SD2_CLK = 126,
+	MX6SLL_PAD_SD2_CMD = 127,
+	MX6SLL_PAD_SD2_DATA0 = 128,
+	MX6SLL_PAD_SD2_DATA1 = 129,
+	MX6SLL_PAD_SD2_DATA2 = 130,
+	MX6SLL_PAD_SD2_DATA3 = 131,
+	MX6SLL_PAD_SD2_DATA4 = 132,
+	MX6SLL_PAD_SD2_DATA5 = 133,
+	MX6SLL_PAD_SD2_DATA6 = 134,
+	MX6SLL_PAD_SD2_DATA7 = 135,
+	MX6SLL_PAD_SD3_CLK = 136,
+	MX6SLL_PAD_SD3_CMD = 137,
+	MX6SLL_PAD_SD3_DATA0 = 138,
+	MX6SLL_PAD_SD3_DATA1 = 139,
+	MX6SLL_PAD_SD3_DATA2 = 140,
+	MX6SLL_PAD_SD3_DATA3 = 141,
+	MX6SLL_PAD_GPIO4_IO20 = 142,
+	MX6SLL_PAD_GPIO4_IO21 = 143,
+	MX6SLL_PAD_GPIO4_IO19 = 144,
+	MX6SLL_PAD_GPIO4_IO25 = 145,
+	MX6SLL_PAD_GPIO4_IO18 = 146,
+	MX6SLL_PAD_GPIO4_IO24 = 147,
+	MX6SLL_PAD_GPIO4_IO23 = 148,
+	MX6SLL_PAD_GPIO4_IO17 = 149,
+	MX6SLL_PAD_GPIO4_IO22 = 150,
+	MX6SLL_PAD_GPIO4_IO16 = 151,
+	MX6SLL_PAD_GPIO4_IO26 = 152,
+};
+
+enum imx6sll_lpsr_pads {
+	MX6SLL_PAD_SNVS_TAMPER = 0,
+	MX6SLL_PAD_SNVS_PMIC_ON_REQ = 1,
+	MX6SLL_PAD_SNVS_PMIC_STBY_REQ = 2,
+	MX6SLL_PAD_SNVS_BOOT_MODE0 = 3,
+	MX6SLL_PAD_SNVS_BOOT_MODE1 = 4,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx6sll_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_RESERVE4),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_WDOG_B),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_24M),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_REF_CLK_32K),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_PWM1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL4),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW4),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL5),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW5),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL6),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW6),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_COL7),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_KEY_ROW7),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA00),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA01),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA02),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA03),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA04),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA05),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA06),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA07),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA08),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA09),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA10),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA11),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA12),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA13),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA14),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_DATA15),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDLE),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDOE),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDSHR),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_SDCE3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDCLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDOE),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDRL),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_GDSP),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_VCOM1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_BDR1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_CTRL3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_COM),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_INT),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_STAT),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_EPDC_PWR_WAKE),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_CLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_ENABLE),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_HSYNC),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_VSYNC),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_RESET),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA00),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA01),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA02),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA03),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA04),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA05),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA06),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA07),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA08),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA09),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA10),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA11),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA12),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA13),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA14),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA15),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA16),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA17),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA18),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA19),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA20),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA21),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA22),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_LCD_DATA23),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXFS),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXC),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_RXD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXC),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXFS),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_TXD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_AUD_MCLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_RXD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_UART1_TXD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SCL),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_I2C1_SDA),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SCL),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_I2C2_SDA),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SCLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MOSI),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_MISO),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI1_SS0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SCLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MOSI),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_MISO),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_ECSPI2_SS0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_CMD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA4),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA5),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA6),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD1_DATA7),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_RESET),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_CMD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA4),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA5),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA6),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD2_DATA7),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CLK),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_CMD),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA0),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA1),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA2),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_SD3_DATA3),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO20),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO21),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO19),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO25),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO18),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO24),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO23),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO17),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO22),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO16),
+	IMX_PINCTRL_PIN(MX6SLL_PAD_GPIO4_IO26),
+};
+
+static struct imx_pinctrl_soc_info imx6sll_pinctrl_info = {
+	.pins = imx6sll_pinctrl_pads,
+	.npins = ARRAY_SIZE(imx6sll_pinctrl_pads),
+	.gpr_compatible = "fsl,imx6sll-iomuxc-gpr",
+};
+
+static const struct of_device_id imx6sll_pinctrl_of_match[] = {
+	{ .compatible = "fsl,imx6sll-iomuxc", .data = &imx6sll_pinctrl_info, },
+	{ /* sentinel */ }
+};
+
+static int imx6sll_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct imx_pinctrl_soc_info *pinctrl_info;
+
+	match = of_match_device(imx6sll_pinctrl_of_match, &pdev->dev);
+
+	if (!match)
+		return -ENODEV;
+
+	pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
+
+	return imx_pinctrl_probe(pdev, pinctrl_info);
+}
+
+static struct platform_driver imx6sll_pinctrl_driver = {
+	.driver = {
+		.name = "imx6sll-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(imx6sll_pinctrl_of_match),
+	},
+	.probe = imx6sll_pinctrl_probe,
+};
+
+static int __init imx6sll_pinctrl_init(void)
+{
+	return platform_driver_register(&imx6sll_pinctrl_driver);
+}
+arch_initcall(imx6sll_pinctrl_init);
+
+static void __exit imx6sll_pinctrl_exit(void)
+{
+	platform_driver_unregister(&imx6sll_pinctrl_driver);
+}
+module_exit(imx6sll_pinctrl_exit);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add pinctrl binding doc update for imx6sll.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 .../bindings/pinctrl/fsl,imx6sll-pinctrl.txt       | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
new file mode 100644
index 0000000..9561c1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
@@ -0,0 +1,37 @@
+* Freescale i.MX6 SLL IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: "fsl,imx6sll-iomuxc"
+- fsl,pins: each entry consists of 6 integers and represents the mux and config
+  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
+  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
+  imx6sll-pinfunc.h under device tree source folder.  The last integer CONFIG is
+  the pad setting value like pull-up on this pin.  Please refer to i.MX6SLL
+  Reference Manual for detailed CONFIG settings.
+
+CONFIG bits definition:
+PAD_CTL_LVE			(1 << 22)
+PAD_CTL_HYS                     (1 << 16)
+PAD_CTL_PUS_100K_DOWN           (0 << 14)
+PAD_CTL_PUS_47K_UP              (1 << 14)
+PAD_CTL_PUS_100K_UP             (2 << 14)
+PAD_CTL_PUS_22K_UP              (3 << 14)
+PAD_CTL_PUE                     (1 << 13)
+PAD_CTL_PKE                     (1 << 12)
+PAD_CTL_ODE                     (1 << 11)
+PAD_CTL_SPEED_LOW               (0 << 6)
+PAD_CTL_SPEED_MED               (1 << 6)
+PAD_CTL_SPEED_HIGH              (3 << 6)
+PAD_CTL_DSE_DISABLE             (0 << 3)
+PAD_CTL_DSE_260ohm              (1 << 3)
+PAD_CTL_DSE_130ohm              (2 << 3)
+PAD_CTL_DSE_87ohm               (3 << 3)
+PAD_CTL_DSE_65ohm               (4 << 3)
+PAD_CTL_DSE_52ohm               (5 << 3)
+PAD_CTL_DSE_43ohm               (6 << 3)
+PAD_CTL_DSE_37ohm               (7 << 3)
+PAD_CTL_SRE_FAST                (1 << 0)
+PAD_CTL_SRE_SLOW                (0 << 0)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 04/12] driver: clk: imx: Add clock driver for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add clk driver support for imx6sll.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 drivers/clk/imx/Makefile                  |   1 +
 drivers/clk/imx/clk-imx6sll.c             | 369 ++++++++++++++++++++++++++++++
 include/dt-bindings/clock/imx6sll-clock.h | 204 +++++++++++++++++
 3 files changed, 574 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imx6sll.c
 create mode 100644 include/dt-bindings/clock/imx6sll-clock.h

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 1ada68a..9fb8e1f 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SOC_IMX35)  += clk-imx35.o
 obj-$(CONFIG_SOC_IMX5)   += clk-imx51-imx53.o
 obj-$(CONFIG_SOC_IMX6Q)  += clk-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
 obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
 obj-$(CONFIG_SOC_IMX7D)  += clk-imx7d.o
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c
new file mode 100644
index 0000000..73758fe1
--- /dev/null
+++ b/drivers/clk/imx/clk-imx6sll.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+#define CCM_ANALOG_PLL_BYPASS		(0x1 << 16)
+#define BM_CCM_CCDR_MMDC_CH0_MASK	(0x2 << 16)
+#define CCDR	0x4
+#define xPLL_CLR(offset)		 (offset + 0x8)
+
+static const char *pll_bypass_src_sels[] = { "osc", "dummy", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *axi_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[] = {"periph", "axi_alt_sel", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ssi_sels[] = {"pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", "dummy",};
+static const char *spdif_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *lcdif_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *lcdif_sels[] = { "lcdif_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static const char *epdc_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *epdc_sels[] = { "epdc_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static struct clk *clks[IMX6SLL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const int clks_init_on[] __initconst = {
+	IMX6SLL_CLK_AIPSTZ1, IMX6SLL_CLK_AIPSTZ2,
+	IMX6SLL_CLK_OCRAM, IMX6SLL_CLK_ARM, IMX6SLL_CLK_ROM,
+	IMX6SLL_CLK_MMDC_P0_FAST, IMX6SLL_CLK_MMDC_P0_IPG,
+};
+
+static const struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ }
+};
+
+static const struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static u32 share_count_audio;
+static u32 share_count_ssi1;
+static u32 share_count_ssi2;
+static u32 share_count_ssi3;
+
+static void __init imx6sll_clocks_init(struct device_node *ccm_node)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int i;
+
+	clks[IMX6SLL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+
+	clks[IMX6SLL_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
+	clks[IMX6SLL_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc");
+
+	/* ipp_di clock is external input */
+	clks[IMX6SLL_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
+	clks[IMX6SLL_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+
+	/* Do not bypass PLLs initially */
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x0));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x10));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x20));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x30));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0x70));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xa0));
+	writel_relaxed(CCM_ANALOG_PLL_BYPASS, base + xPLL_CLR(0xe0));
+
+	clks[IMX6SLL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SLL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+	clks[IMX6SLL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS,	 "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+	clks[IMX6SLL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+	clks[IMX6SLL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB,	 "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+	clks[IMX6SLL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV,	 "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+	clks[IMX6SLL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV,	 "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+	clks[IMX6SLL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET,	 "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+	clks[IMX6SLL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB,	 "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+
+	clks[IMX6SLL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
+	clks[IMX6SLL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
+
+	clks[IMX6SLL_CLK_PLL1_SYS]	= imx_clk_fixed_factor("pll1_sys",	"pll1_bypass", 1, 1);
+	clks[IMX6SLL_CLK_PLL2_BUS]	= imx_clk_gate("pll2_bus",		"pll2_bypass", base + 0x30, 13);
+	clks[IMX6SLL_CLK_PLL3_USB_OTG]	= imx_clk_gate("pll3_usb_otg",		"pll3_bypass", base + 0x10, 13);
+	clks[IMX6SLL_CLK_PLL4_AUDIO]	= imx_clk_gate("pll4_audio",		"pll4_bypass", base + 0x70, 13);
+	clks[IMX6SLL_CLK_PLL5_VIDEO]	= imx_clk_gate("pll5_video",		"pll5_bypass", base + 0xa0, 13);
+	clks[IMX6SLL_CLK_PLL6_ENET]	= imx_clk_gate("pll6_enet",		"pll6_bypass", base + 0xe0, 13);
+	clks[IMX6SLL_CLK_PLL7_USB_HOST]	= imx_clk_gate("pll7_usb_host",		"pll7_bypass", base + 0x20, 13);
+
+	/*
+	 * Bit 20 is the reserved and read-only bit, we do this only for:
+	 * - Do nothing for usbphy clk_enable/disable
+	 * - Keep refcount when do usbphy clk_enable/disable, in that case,
+	 * the clk framework many need to enable/disable usbphy's parent
+	 */
+	clks[IMX6SLL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg",  base + 0x10, 20);
+	clks[IMX6SLL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+	/*
+	 * usbphy*_gate needs to be on after system boots up, and software
+	 * never needs to control it anymore.
+	 */
+	clks[IMX6SLL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+	clks[IMX6SLL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+	/*					name		   parent_name	   reg		idx */
+	clks[IMX6SLL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",	   base + 0x100, 0);
+	clks[IMX6SLL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",	   base + 0x100, 1);
+	clks[IMX6SLL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",	   base + 0x100, 2);
+	clks[IMX6SLL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus",	   base + 0x100, 3);
+	clks[IMX6SLL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
+	clks[IMX6SLL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
+	clks[IMX6SLL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,	 2);
+	clks[IMX6SLL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,	 3);
+
+	clks[IMX6SLL_CLK_PLL4_POST_DIV]  = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio",
+		 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+	clks[IMX6SLL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div",
+		 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+	clks[IMX6SLL_CLK_PLL5_POST_DIV]  = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video",
+		 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+	clks[IMX6SLL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div",
+		 CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
+	/*						   name		parent_name	 mult  div */
+	clks[IMX6SLL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1,	2);
+	clks[IMX6SLL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1,    4);
+	clks[IMX6SLL_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 	6);
+	clks[IMX6SLL_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 	8);
+
+	np = ccm_node;
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+
+	clks[IMX6SLL_CLK_STEP] 	 	  = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+	clks[IMX6SLL_CLK_PLL1_SW] 	  = imx_clk_mux_flags("pll1_sw",   base + 0x0c, 2,  1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0);
+	clks[IMX6SLL_CLK_AXI_ALT_SEL]	  = imx_clk_mux("axi_alt_sel",		base + 0x14, 7,  1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
+	clks[IMX6SLL_CLK_AXI_SEL] 	  = imx_clk_mux_flags("axi_sel", 	base + 0x14, 6,  1, axi_sels, ARRAY_SIZE(axi_sels), 0);
+	clks[IMX6SLL_CLK_PERIPH_PRE]	  = imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+	clks[IMX6SLL_CLK_PERIPH2_PRE]	  = imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+	clks[IMX6SLL_CLK_PERIPH_CLK2_SEL]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6SLL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+	clks[IMX6SLL_CLK_USDHC2_SEL]	  = imx_clk_mux("usdhc2_sel",   base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SLL_CLK_USDHC1_SEL]	  = imx_clk_mux("usdhc1_sel",   base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SLL_CLK_USDHC3_SEL]	  = imx_clk_mux("usdhc3_sel",   base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SLL_CLK_SSI1_SEL]	  = imx_clk_mux("ssi1_sel",     base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+	clks[IMX6SLL_CLK_SSI2_SEL]	  = imx_clk_mux("ssi2_sel",     base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+	clks[IMX6SLL_CLK_SSI3_SEL]	  = imx_clk_mux("ssi3_sel",     base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+	clks[IMX6SLL_CLK_PERCLK_SEL] 	  = imx_clk_mux("perclk_sel",	base + 0x1c, 6,  1, perclk_sels, ARRAY_SIZE(perclk_sels));
+	clks[IMX6SLL_CLK_UART_SEL]	  = imx_clk_mux("uart_sel",	base + 0x24, 6,  1, uart_sels, ARRAY_SIZE(uart_sels));
+	clks[IMX6SLL_CLK_SPDIF_SEL]	  = imx_clk_mux("spdif_sel",	base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+	clks[IMX6SLL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel",   base + 0x30, 7,  2, spdif_sels, ARRAY_SIZE(spdif_sels));
+	clks[IMX6SLL_CLK_EPDC_PRE_SEL]	  = imx_clk_mux("epdc_pre_sel",	base + 0x34, 15, 3, epdc_pre_sels, ARRAY_SIZE(epdc_pre_sels));
+	clks[IMX6SLL_CLK_EPDC_SEL]	  = imx_clk_mux("epdc_sel",	base + 0x34, 9, 3, epdc_sels, ARRAY_SIZE(epdc_sels));
+	clks[IMX6SLL_CLK_ECSPI_SEL]	  = imx_clk_mux("ecspi_sel",	base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+	clks[IMX6SLL_CLK_LCDIF_PRE_SEL]	  = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
+	clks[IMX6SLL_CLK_LCDIF_SEL]	  = imx_clk_mux("lcdif_sel", 	base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+
+	clks[IMX6SLL_CLK_PERIPH]  = imx_clk_busy_mux("periph",  base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+	clks[IMX6SLL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+	clks[IMX6SLL_CLK_PERIPH_CLK2]	= imx_clk_divider("periph_clk2",   "periph_clk2_sel",  	base + 0x14, 27, 3);
+	clks[IMX6SLL_CLK_PERIPH2_CLK2]	= imx_clk_divider("periph2_clk2",  "periph2_clk2_sel", 	base + 0x14, 0,  3);
+	clks[IMX6SLL_CLK_IPG]		= imx_clk_divider("ipg",	   "ahb",		base + 0x14, 8,	 2);
+	clks[IMX6SLL_CLK_LCDIF_PODF]	= imx_clk_divider("lcdif_podf",	   "lcdif_pred",	base + 0x18, 23, 3);
+	clks[IMX6SLL_CLK_PERCLK]	= imx_clk_divider("perclk",	   "perclk_sel",	base + 0x1c, 0,  6);
+	clks[IMX6SLL_CLK_USDHC3_PODF]   = imx_clk_divider("usdhc3_podf",   "usdhc3_sel",	base + 0x24, 19, 3);
+	clks[IMX6SLL_CLK_USDHC2_PODF]	= imx_clk_divider("usdhc2_podf",   "usdhc2_sel",	base + 0x24, 16, 3);
+	clks[IMX6SLL_CLK_USDHC1_PODF]	= imx_clk_divider("usdhc1_podf",   "usdhc1_sel",	base + 0x24, 11, 3);
+	clks[IMX6SLL_CLK_UART_PODF]	= imx_clk_divider("uart_podf",	   "uart_sel",		base + 0x24, 0,  6);
+	clks[IMX6SLL_CLK_SSI3_PRED]	= imx_clk_divider("ssi3_pred",	   "ssi3_sel",		base + 0x28, 22, 3);
+	clks[IMX6SLL_CLK_SSI3_PODF]	= imx_clk_divider("ssi3_podf",	   "ssi3_pred",		base + 0x28, 16, 6);
+	clks[IMX6SLL_CLK_SSI1_PRED]	= imx_clk_divider("ssi1_pred",	   "ssi1_sel",		base + 0x28, 6,	 3);
+	clks[IMX6SLL_CLK_SSI1_PODF]	= imx_clk_divider("ssi1_podf",	   "ssi1_pred",		base + 0x28, 0,	 6);
+	clks[IMX6SLL_CLK_SSI2_PRED]	= imx_clk_divider("ssi2_pred",	   "ssi2_sel",		base + 0x2c, 6,	 3);
+	clks[IMX6SLL_CLK_SSI2_PODF]	= imx_clk_divider("ssi2_podf",	   "ssi2_pred",		base + 0x2c, 0,  6);
+	clks[IMX6SLL_CLK_SPDIF_PRED]	= imx_clk_divider("spdif_pred",	   "spdif_sel",		base + 0x30, 25, 3);
+	clks[IMX6SLL_CLK_SPDIF_PODF]	= imx_clk_divider("spdif_podf",	   "spdif_pred",	base + 0x30, 22, 3);
+	clks[IMX6SLL_CLK_EXTERN_AUDIO_PRED]   = imx_clk_divider("extern_audio_pred",   "extern_audio_sel",        base + 0x30, 12, 3);
+	clks[IMX6SLL_CLK_EXTERN_AUDIO_PODF]   = imx_clk_divider("extern_audio_podf",   "extern_audio_pred",       base + 0x30, 9,  3);
+	clks[IMX6SLL_CLK_EPDC_PODF]	= imx_clk_divider("epdc_podf",	   "epdc_pre_sel",	base + 0x34, 12, 3);
+	clks[IMX6SLL_CLK_ECSPI_PODF]	= imx_clk_divider("ecspi_podf",	   "ecspi_sel",		base + 0x38, 19, 6);
+	clks[IMX6SLL_CLK_LCDIF_PRED]	= imx_clk_divider("lcdif_pred",	   "lcdif_pre_sel",	base + 0x38, 12, 3);
+
+	clks[IMX6SLL_CLK_ARM]		= imx_clk_busy_divider("arm", 	    "pll1_sw",	base +	0x10, 0,  3,  base + 0x48, 16);
+	clks[IMX6SLL_CLK_MMDC_PODF]	= imx_clk_busy_divider("mmdc_podf", "periph2",	base +  0x14, 3,  3,  base + 0x48, 2);
+	clks[IMX6SLL_CLK_AXI_PODF]	= imx_clk_busy_divider("axi",       "axi_sel",	base +  0x14, 16, 3,  base + 0x48, 0);
+	clks[IMX6SLL_CLK_AHB]		= imx_clk_busy_divider("ahb",	    "periph",	base +  0x14, 10, 3,  base + 0x48, 1);
+
+	clks[IMX6SLL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[IMX6SLL_CLK_LDB_DI0_DIV_7]	  = imx_clk_fixed_factor("ldb_di0_div_7",   "ldb_di0_sel", 1, 7);
+	clks[IMX6SLL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[IMX6SLL_CLK_LDB_DI1_DIV_7]	  = imx_clk_fixed_factor("ldb_di1_div_7",   "ldb_di1_sel", 1, 7);
+
+	clks[IMX6SLL_CLK_LDB_DI0_SEL]	= imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
+	clks[IMX6SLL_CLK_LDB_DI1_SEL]   = imx_clk_mux("ldb_di1_sel", base + 0x1c, 7, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels));
+	clks[IMX6SLL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+	clks[IMX6SLL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1_div_sel", base + 0x20, 10, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+
+	/* CCGR0 */
+	clks[IMX6SLL_CLK_AIPSTZ1]	= imx_clk_gate2("aips_tz1", 	"ahb",		base + 0x68,	0);
+	clks[IMX6SLL_CLK_AIPSTZ2]	= imx_clk_gate2("aips_tz2", 	"ahb",		base + 0x68,	2);
+	clks[IMX6SLL_CLK_DCP]		= imx_clk_gate2("dcp",		"ahb",		base + 0x68,	10);
+	clks[IMX6SLL_CLK_UART2_IPG]	= imx_clk_gate2("uart2_ipg",	"ipg",		base + 0x68,	28);
+	clks[IMX6SLL_CLK_UART2_SERIAL]	= imx_clk_gate2("uart2_serial",	"uart_podf",	base + 0x68,	28);
+
+	/* CCGR1 */
+	clks[IMX6SLL_CLK_ECSPI1]	= imx_clk_gate2("ecspi1",	"ecspi_podf",	base + 0x6c,	0);
+	clks[IMX6SLL_CLK_ECSPI2]	= imx_clk_gate2("ecspi2",	"ecspi_podf",	base + 0x6c,	2);
+	clks[IMX6SLL_CLK_ECSPI3]	= imx_clk_gate2("ecspi3",	"ecspi_podf",	base + 0x6c,	4);
+	clks[IMX6SLL_CLK_ECSPI4]	= imx_clk_gate2("ecspi4",	"ecspi_podf",	base + 0x6c,	6);
+	clks[IMX6SLL_CLK_UART3_IPG]	= imx_clk_gate2("uart3_ipg",	"ipg",		base + 0x6c,	10);
+	clks[IMX6SLL_CLK_UART3_SERIAL]	= imx_clk_gate2("uart3_serial",	"uart_podf",	base + 0x6c,	10);
+	clks[IMX6SLL_CLK_EPIT1]		= imx_clk_gate2("epit1",	"perclk",	base + 0x6c,	12);
+	clks[IMX6SLL_CLK_EPIT2]		= imx_clk_gate2("epit2",	"perclk",	base + 0x6c,	14);
+	clks[IMX6SLL_CLK_GPT_BUS]	= imx_clk_gate2("gpt1_bus",	"perclk",	base + 0x6c,	20);
+	clks[IMX6SLL_CLK_GPT_SERIAL]	= imx_clk_gate2("gpt1_serial",	"perclk",	base + 0x6c,	22);
+	clks[IMX6SLL_CLK_UART4_IPG]	= imx_clk_gate2("uart4_ipg",	"ipg",		base + 0x6c,	24);
+	clks[IMX6SLL_CLK_UART4_SERIAL]	= imx_clk_gate2("uart4_serail",	"uart_podf",	base + 0x6c,	24);
+
+	/* CCGR2 */
+	clks[IMX6SLL_CLK_CSI]		= imx_clk_gate2("csi",		"axi",		base + 0x70,	2);
+	clks[IMX6SLL_CLK_I2C1]		= imx_clk_gate2("i2c1",		"perclk",	base + 0x70,	6);
+	clks[IMX6SLL_CLK_I2C2]		= imx_clk_gate2("i2c2",		"perclk",	base + 0x70,	8);
+	clks[IMX6SLL_CLK_I2C3]		= imx_clk_gate2("i2c3",		"perclk",	base + 0x70,	10);
+	clks[IMX6SLL_CLK_OCOTP]		= imx_clk_gate2("ocotp",	"ipg",		base + 0x70,	12);
+	clks[IMX6SLL_CLK_LCDIF_APB]	= imx_clk_gate2("lcdif_apb",	"axi",		base + 0x70,	28);
+	clks[IMX6SLL_CLK_PXP]		= imx_clk_gate2("pxp",		"axi",		base + 0x70,	30);
+
+	/* CCGR3 */
+	clks[IMX6SLL_CLK_UART5_IPG]	= imx_clk_gate2("uart5_ipg",	"ipg",		base + 0x74,	2);
+	clks[IMX6SLL_CLK_UART5_SERIAL]	= imx_clk_gate2("uart5_serial",	"uart_podf",	base + 0x74,	2);
+	clks[IMX6SLL_CLK_EPDC_AXI]	= imx_clk_gate2("epdc_aclk",	"axi",		base + 0x74,	4);
+	clks[IMX6SLL_CLK_EPDC_PIX]	= imx_clk_gate2("epdc_pix",	"epdc_podf",	base + 0x74,	4);
+	clks[IMX6SLL_CLK_LCDIF_PIX]	= imx_clk_gate2("lcdif_pix",	"lcdif_podf",	base + 0x74,	10);
+	clks[IMX6SLL_CLK_WDOG1]		= imx_clk_gate2("wdog1",	"ipg",		base + 0x74,	16);
+	clks[IMX6SLL_CLK_MMDC_P0_FAST]	= imx_clk_gate("mmdc_p0_fast",  "mmdc_podf",	base + 0x74,	20);
+	clks[IMX6SLL_CLK_MMDC_P0_IPG]	= imx_clk_gate2("mmdc_p0_ipg",	"ipg",		base + 0x74,	24);
+	clks[IMX6SLL_CLK_OCRAM]		= imx_clk_gate("ocram",		"ahb",		base + 0x74,	28);
+
+	/* CCGR4 */
+	clks[IMX6SLL_CLK_PWM1]		= imx_clk_gate2("pwm1",		"perclk",	base + 0x78,	16);
+	clks[IMX6SLL_CLK_PWM2]		= imx_clk_gate2("pwm2",		"perclk",	base + 0x78,	18);
+	clks[IMX6SLL_CLK_PWM3]		= imx_clk_gate2("pwm3",		"perclk",	base + 0x78,	20);
+	clks[IMX6SLL_CLK_PWM4]		= imx_clk_gate2("pwm4",		"perclk",	base + 0x78,	22);
+
+	/* CCGR5 */
+	clks[IMX6SLL_CLK_ROM]		= imx_clk_gate2("rom",		"ahb",		base + 0x7c,	0);
+	clks[IMX6SLL_CLK_SDMA]		= imx_clk_gate2("sdma",		"ahb",		base + 0x7c,	6);
+	clks[IMX6SLL_CLK_WDOG2]		= imx_clk_gate2("wdog2",	"ipg",		base + 0x7c,	10);
+	clks[IMX6SLL_CLK_SPBA]		= imx_clk_gate2("spba",		"ipg",		base + 0x7c,	12);
+	clks[IMX6SLL_CLK_EXTERN_AUDIO]	= imx_clk_gate2_shared("extern_audio",	"extern_audio_podf",	base + 0x7c,	14, &share_count_audio);
+	clks[IMX6SLL_CLK_SPDIF]		= imx_clk_gate2_shared("spdif",		"spdif_podf",	base + 0x7c,	14, &share_count_audio);
+	clks[IMX6SLL_CLK_SPDIF_GCLK]	= imx_clk_gate2_shared("spdif_gclk",	"ipg",		base + 0x7c,	14, &share_count_audio);
+	clks[IMX6SLL_CLK_SSI1]		= imx_clk_gate2_shared("ssi1",		"ssi1_podf",	base + 0x7c, 	18, &share_count_ssi1);
+	clks[IMX6SLL_CLK_SSI1_IPG]	= imx_clk_gate2_shared("ssi1_ipg",	"ipg",		base + 0x7c, 	18, &share_count_ssi1);
+	clks[IMX6SLL_CLK_SSI2]		= imx_clk_gate2_shared("ssi2",		"ssi2_podf",	base + 0x7c, 	20, &share_count_ssi2);
+	clks[IMX6SLL_CLK_SSI2_IPG]	= imx_clk_gate2_shared("ssi2_ipg",	"ipg",		base + 0x7c, 	20, &share_count_ssi2);
+	clks[IMX6SLL_CLK_SSI3]		= imx_clk_gate2_shared("ssi3",		"ssi3_podf",	base + 0x7c, 	22, &share_count_ssi3);
+	clks[IMX6SLL_CLK_SSI3_IPG]	= imx_clk_gate2_shared("ssi3_ipg",	"ipg",		base + 0x7c, 	22, &share_count_ssi3);
+	clks[IMX6SLL_CLK_UART1_IPG]	= imx_clk_gate2("uart1_ipg",	"ipg",		base + 0x7c,	24);
+	clks[IMX6SLL_CLK_UART1_SERIAL]	= imx_clk_gate2("uart1_serial",	"uart_podf",	base + 0x7c,	24);
+
+	/* CCGR6 */
+	clks[IMX6SLL_CLK_USBOH3]	= imx_clk_gate2("usboh3",	"ipg",		 base + 0x80,	0);
+	clks[IMX6SLL_CLK_USDHC1]	= imx_clk_gate2("usdhc1",	"usdhc1_podf",	 base + 0x80,	2);
+	clks[IMX6SLL_CLK_USDHC2]	= imx_clk_gate2("usdhc2",	"usdhc2_podf",	 base + 0x80,	4);
+	clks[IMX6SLL_CLK_USDHC3]	= imx_clk_gate2("usdhc3",	"usdhc3_podf",	 base + 0x80,	6);
+
+	/* mask handshake of mmdc */
+	writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+	for (i = 0; i < ARRAY_SIZE(clks); i++)
+		if (IS_ERR(clks[i]))
+			pr_err("i.MX6SLL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	/* set perclk to from OSC */
+	clk_set_parent(clks[IMX6SLL_CLK_PERCLK_SEL], clks[IMX6SLL_CLK_OSC]);
+
+	for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+		clk_prepare_enable(clks[clks_init_on[i]]);
+
+	if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+		clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY1_GATE]);
+		clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY2_GATE]);
+	}
+
+	/* Lower the AHB clock rate before changing the clock source. */
+	clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000);
+
+	/* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+	clk_set_parent(clks[IMX6SLL_CLK_PERIPH_CLK2_SEL], clks[IMX6SLL_CLK_PLL3_USB_OTG]);
+	clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_CLK2]);
+	clk_set_parent(clks[IMX6SLL_CLK_PERIPH_PRE], clks[IMX6SLL_CLK_PLL2_BUS]);
+	clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_PRE]);
+
+	clk_set_rate(clks[IMX6SLL_CLK_AHB], 132000000);
+}
+
+CLK_OF_DECLARE(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init);
+
diff --git a/include/dt-bindings/clock/imx6sll-clock.h b/include/dt-bindings/clock/imx6sll-clock.h
new file mode 100644
index 0000000..39c2567
--- /dev/null
+++ b/include/dt-bindings/clock/imx6sll-clock.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX6SLL_H
+#define __DT_BINDINGS_CLOCK_IMX6SLL_H
+
+#define IMX6SLL_CLK_DUMMY		0
+#define IMX6SLL_CLK_CKIL		1
+#define IMX6SLL_CLK_OSC			2
+#define IMX6SLL_PLL1_BYPASS_SRC		3
+#define IMX6SLL_PLL2_BYPASS_SRC		4
+#define IMX6SLL_PLL3_BYPASS_SRC		5
+#define IMX6SLL_PLL4_BYPASS_SRC		6
+#define IMX6SLL_PLL5_BYPASS_SRC		7
+#define IMX6SLL_PLL6_BYPASS_SRC		8
+#define IMX6SLL_PLL7_BYPASS_SRC		9
+#define IMX6SLL_CLK_PLL1		10
+#define IMX6SLL_CLK_PLL2		11
+#define IMX6SLL_CLK_PLL3		12
+#define IMX6SLL_CLK_PLL4		13
+#define IMX6SLL_CLK_PLL5		14
+#define IMX6SLL_CLK_PLL6		15
+#define IMX6SLL_CLK_PLL7		16
+#define IMX6SLL_PLL1_BYPASS		17
+#define IMX6SLL_PLL2_BYPASS		18
+#define IMX6SLL_PLL3_BYPASS		19
+#define IMX6SLL_PLL4_BYPASS		20
+#define IMX6SLL_PLL5_BYPASS		21
+#define IMX6SLL_PLL6_BYPASS		22
+#define IMX6SLL_PLL7_BYPASS		23
+#define IMX6SLL_CLK_PLL1_SYS		24
+#define IMX6SLL_CLK_PLL2_BUS		25
+#define IMX6SLL_CLK_PLL3_USB_OTG	26
+#define IMX6SLL_CLK_PLL4_AUDIO		27
+#define IMX6SLL_CLK_PLL5_VIDEO		28
+#define IMX6SLL_CLK_PLL6_ENET		29
+#define IMX6SLL_CLK_PLL7_USB_HOST	30
+#define IMX6SLL_CLK_USBPHY1		31
+#define IMX6SLL_CLK_USBPHY2		32
+#define IMX6SLL_CLK_USBPHY1_GATE	33
+#define IMX6SLL_CLK_USBPHY2_GATE	34
+#define IMX6SLL_CLK_PLL2_PFD0		35
+#define IMX6SLL_CLK_PLL2_PFD1		36
+#define IMX6SLL_CLK_PLL2_PFD2		37
+#define IMX6SLL_CLK_PLL2_PFD3		38
+#define IMX6SLL_CLK_PLL3_PFD0		39
+#define IMX6SLL_CLK_PLL3_PFD1		40
+#define IMX6SLL_CLK_PLL3_PFD2		41
+#define IMX6SLL_CLK_PLL3_PFD3		42
+#define IMX6SLL_CLK_PLL4_POST_DIV	43
+#define IMX6SLL_CLK_PLL4_AUDIO_DIV	44
+#define IMX6SLL_CLK_PLL5_POST_DIV	45
+#define IMX6SLL_CLK_PLL5_VIDEO_DIV	46
+#define IMX6SLL_CLK_PLL2_198M		47
+#define IMX6SLL_CLK_PLL3_120M		48
+#define IMX6SLL_CLK_PLL3_80M		49
+#define IMX6SLL_CLK_PLL3_60M		50
+#define IMX6SLL_CLK_STEP		51
+#define IMX6SLL_CLK_PLL1_SW		52
+#define IMX6SLL_CLK_AXI_ALT_SEL		53
+#define IMX6SLL_CLK_AXI_SEL		54
+#define IMX6SLL_CLK_PERIPH_PRE		55
+#define IMX6SLL_CLK_PERIPH2_PRE		56
+#define IMX6SLL_CLK_PERIPH_CLK2_SEL	57
+#define IMX6SLL_CLK_PERIPH2_CLK2_SEL	58
+#define IMX6SLL_CLK_PERCLK_SEL		59
+#define IMX6SLL_CLK_USDHC1_SEL		60
+#define IMX6SLL_CLK_USDHC2_SEL		61
+#define IMX6SLL_CLK_USDHC3_SEL		62
+#define IMX6SLL_CLK_SSI1_SEL		63
+#define IMX6SLL_CLK_SSI2_SEL		64
+#define IMX6SLL_CLK_SSI3_SEL		65
+#define IMX6SLL_CLK_PXP_SEL		66
+#define IMX6SLL_CLK_LCDIF_PRE_SEL	67
+#define IMX6SLL_CLK_LCDIF_SEL		68
+#define IMX6SLL_CLK_EPDC_PRE_SEL	69
+#define IMX6SLL_CLK_SPDIF_SEL		70
+#define IMX6SLL_CLK_ECSPI_SEL		71
+#define IMX6SLL_CLK_UART_SEL		72
+#define IMX6SLL_CLK_ARM			73
+#define IMX6SLL_CLK_PERIPH		74
+#define IMX6SLL_CLK_PERIPH2		75
+#define IMX6SLL_CLK_PERIPH2_CLK2	76
+#define IMX6SLL_CLK_PERIPH_CLK2		77
+#define IMX6SLL_CLK_MMDC_PODF		78
+#define IMX6SLL_CLK_AXI_PODF		79
+#define IMX6SLL_CLK_AHB			80
+#define IMX6SLL_CLK_IPG			81
+#define IMX6SLL_CLK_PERCLK		82
+#define IMX6SLL_CLK_USDHC1_PODF		83
+#define IMX6SLL_CLK_USDHC2_PODF		84
+#define IMX6SLL_CLK_USDHC3_PODF		85
+#define IMX6SLL_CLK_SSI1_PRED		86
+#define IMX6SLL_CLK_SSI2_PRED		87
+#define IMX6SLL_CLK_SSI3_PRED		88
+#define IMX6SLL_CLK_SSI1_PODF		89
+#define IMX6SLL_CLK_SSI2_PODF		90
+#define IMX6SLL_CLK_SSI3_PODF		91
+#define IMX6SLL_CLK_PXP_PODF		92
+#define IMX6SLL_CLK_LCDIF_PRED		93
+#define IMX6SLL_CLK_LCDIF_PODF		94
+#define IMX6SLL_CLK_EPDC_SEL		95
+#define IMX6SLL_CLK_EPDC_PODF		96
+#define IMX6SLL_CLK_SPDIF_PRED		97
+#define IMX6SLL_CLK_SPDIF_PODF		98
+#define IMX6SLL_CLK_ECSPI_PODF		99
+#define IMX6SLL_CLK_UART_PODF		100
+
+/* CCGR 0 */
+#define IMX6SLL_CLK_AIPSTZ1		101
+#define IMX6SLL_CLK_AIPSTZ2		102
+#define IMX6SLL_CLK_DCP			103
+#define IMX6SLL_CLK_UART2_IPG		104
+#define IMX6SLL_CLK_UART2_SERIAL	105
+
+/* CCGR 1 */
+#define IMX6SLL_CLK_ECSPI1		106
+#define IMX6SLL_CLK_ECSPI2		107
+#define IMX6SLL_CLK_ECSPI3		108
+#define IMX6SLL_CLK_ECSPI4		109
+#define IMX6SLL_CLK_UART3_IPG		110
+#define IMX6SLL_CLK_UART3_SERIAL	111
+#define IMX6SLL_CLK_UART4_IPG		112
+#define IMX6SLL_CLK_UART4_SERIAL	113
+#define IMX6SLL_CLK_EPIT1		114
+#define IMX6SLL_CLK_EPIT2		115
+#define IMX6SLL_CLK_GPT_BUS		116
+#define IMX6SLL_CLK_GPT_SERIAL		117
+
+/* CCGR2 */
+#define IMX6SLL_CLK_CSI			118
+#define IMX6SLL_CLK_I2C1		119
+#define IMX6SLL_CLK_I2C2		120
+#define IMX6SLL_CLK_I2C3		121
+#define IMX6SLL_CLK_OCOTP		122
+#define IMX6SLL_CLK_LCDIF_APB		123
+#define IMX6SLL_CLK_PXP			124
+
+/* CCGR3 */
+#define IMX6SLL_CLK_UART5_IPG		125
+#define IMX6SLL_CLK_UART5_SERIAL	126
+#define IMX6SLL_CLK_EPDC_AXI		127
+#define IMX6SLL_CLK_EPDC_PIX		128
+#define IMX6SLL_CLK_LCDIF_PIX		129
+#define IMX6SLL_CLK_WDOG1		130
+#define IMX6SLL_CLK_MMDC_P0_FAST	131
+#define IMX6SLL_CLK_MMDC_P0_IPG		132
+#define IMX6SLL_CLK_OCRAM		133
+
+/* CCGR4 */
+#define IMX6SLL_CLK_PWM1		134
+#define IMX6SLL_CLK_PWM2		135
+#define IMX6SLL_CLK_PWM3		136
+#define IMX6SLL_CLK_PWM4		137
+
+/* CCGR 5 */
+#define IMX6SLL_CLK_ROM			138
+#define IMX6SLL_CLK_SDMA		139
+#define IMX6SLL_CLK_KPP			140
+#define IMX6SLL_CLK_WDOG2		141
+#define IMX6SLL_CLK_SPBA		142
+#define IMX6SLL_CLK_SPDIF		143
+#define IMX6SLL_CLK_SPDIF_GCLK		144
+#define IMX6SLL_CLK_SSI1		145
+#define IMX6SLL_CLK_SSI1_IPG		146
+#define IMX6SLL_CLK_SSI2		147
+#define IMX6SLL_CLK_SSI2_IPG		148
+#define IMX6SLL_CLK_SSI3		149
+#define IMX6SLL_CLK_SSI3_IPG		150
+#define IMX6SLL_CLK_UART1_IPG		151
+#define IMX6SLL_CLK_UART1_SERIAL	152
+
+/* CCGR 6 */
+#define IMX6SLL_CLK_USBOH3		153
+#define IMX6SLL_CLK_USDHC1		154
+#define IMX6SLL_CLK_USDHC2		155
+#define IMX6SLL_CLK_USDHC3		156
+
+#define IMX6SLL_CLK_IPP_DI0		157
+#define IMX6SLL_CLK_IPP_DI1		158
+#define IMX6SLL_CLK_LDB_DI0_SEL		159
+#define IMX6SLL_CLK_LDB_DI0_DIV_3_5	160
+#define IMX6SLL_CLK_LDB_DI0_DIV_7	161
+#define IMX6SLL_CLK_LDB_DI0_DIV_SEL	162
+#define IMX6SLL_CLK_LDB_DI0		163
+#define IMX6SLL_CLK_LDB_DI1_SEL		164
+#define IMX6SLL_CLK_LDB_DI1_DIV_3_5	165
+#define IMX6SLL_CLK_LDB_DI1_DIV_7	166
+#define IMX6SLL_CLK_LDB_DI1_DIV_SEL	167
+#define IMX6SLL_CLK_LDB_DI1		168
+#define IMX6SLL_CLK_EXTERN_AUDIO_SEL    169
+#define IMX6SLL_CLK_EXTERN_AUDIO_PRED   170
+#define IMX6SLL_CLK_EXTERN_AUDIO_PODF   171
+#define IMX6SLL_CLK_EXTERN_AUDIO        172
+
+#define IMX6SLL_CLK_END			173
+
+#endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 03/12] Document: dt: binding: imx: update clock doc for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add clock binding doc uppdate for imx6sll.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 .../devicetree/bindings/clock/imx6sll-clock.txt    | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6sll-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/imx6sll-clock.txt b/Documentation/devicetree/bindings/clock/imx6sll-clock.txt
new file mode 100644
index 0000000..3a46787
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx6sll-clock.txt
@@ -0,0 +1,37 @@
+* Clock bindings for Freescale i.MX6 SLL
+
+Required properties:
+- compatible: Should be "fsl,imx6sll-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+- clocks: list of clock specifiers, must contain an entry for each required
+  entry in clock-names
+- clock-names: should include entries "ckil", "osc", "ipp_di0" and "ipp_di1"
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.  See include/dt-bindings/clock/imx6sll-clock.h
+for the full list of i.MX6 SLL clock IDs.
+
+Examples:
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+
+clks: ccm at 020c4000 {
+		compatible = "fsl,imx6sll-ccm";
+		reg = <0x020c4000 0x4000>;
+		interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+		#clock-cells = <1>;
+		clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+		clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+};
+
+uart1: serial at 02020000 {
+		compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart", "fsl,imx21-uart";
+		reg = <0x02020000 0x4000>;
+		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX6SLL_CLK_UART1_IPG>,
+			 <&clks IMX6SLL_CLK_UART1_SERIAL>;
+		clock-names = "ipg", "per";
+		status = "disabled";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 02/12] driver: clocksource: add gpt timer for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add gpt timer support for i.MX6SLL.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 drivers/clocksource/timer-imx-gpt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c
index f595460..f71822d 100644
--- a/drivers/clocksource/timer-imx-gpt.c
+++ b/drivers/clocksource/timer-imx-gpt.c
@@ -556,4 +556,5 @@ static int __init imx6dl_timer_init_dt(struct device_node *np)
 CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sll_timer, "fsl,imx6sll-gpt", imx6dl_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 01/12] ARM: imx: Add basic msl support for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

Add basic MSL support for i.MX6SLL.

The i.MX 6SoloLiteLite application processors are NXP's latest
additions to a growing family of multimedia-focused products
offering high-performance processing optimized for lowest power
consumption. The i.MX 6SoloLiteLite processors feature NXP's advanced
implementation of the ARM Cortex-A9 core, which can be interfaced
with LPDDR3 and LPDDR2 DRAM memory devices.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
---
 arch/arm/mach-imx/Kconfig          |  7 +++++++
 arch/arm/mach-imx/Makefile         |  1 +
 arch/arm/mach-imx/cpu.c            |  3 +++
 arch/arm/mach-imx/cpuidle-imx6sl.c |  7 +++++--
 arch/arm/mach-imx/gpc.c            |  8 ++++++++
 arch/arm/mach-imx/mach-imx6sl.c    | 10 ++++++++--
 arch/arm/mach-imx/mxc.h            |  6 ++++++
 7 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 936c59d..33bcfda 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -512,6 +512,13 @@ config SOC_IMX6SL
 	help
 	  This enables support for Freescale i.MX6 SoloLite processor.
 
+config SOC_IMX6SLL
+	bool "i.MX6 SoloLiteLite support"
+	select SOC_IMX6
+
+	help
+	  This enables support for Freescale i.MX6 SoloLiteLite processor.
+
 config SOC_IMX6SX
 	bool "i.MX6 SoloX support"
 	select PINCTRL_IMX6SX
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index cab1289..f2bf650 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 endif
 obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
 obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index b3347d3..62e8c0f 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void)
 	case MXC_CPU_IMX6UL:
 		soc_id = "i.MX6UL";
 		break;
+	case MXC_CPU_IMX6SLL:
+		soc_id = "i.MX6SLL";
+		break;
 	case MXC_CPU_IMX7D:
 		soc_id = "i.MX7D";
 		break;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 8d866fb..124f982 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -11,6 +11,7 @@
 #include <asm/cpuidle.h>
 
 #include "common.h"
+#include "hardware.h"
 #include "cpuidle.h"
 
 static int imx6sl_enter_wait(struct cpuidle_device *dev,
@@ -21,9 +22,11 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
 	 * Software workaround for ERR005311, see function
 	 * description for details.
 	 */
-	imx6sl_set_wait_clk(true);
+	if (cpu_is_imx6sl())
+		imx6sl_set_wait_clk(true);
 	cpu_do_idle();
-	imx6sl_set_wait_clk(false);
+	if (cpu_is_imx6sl())
+		imx6sl_set_wait_clk(false);
 	imx6_set_lpm(WAIT_CLOCKED);
 
 	return index;
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 1dc2a34..4ed8a63 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -26,6 +26,7 @@
 #include "hardware.h"
 
 #define GPC_CNTR		0x000
+#define GPC_CNTR_L2_PGE		22
 #define GPC_IMR1		0x008
 #define GPC_PGC_GPU_PDN		0x260
 #define GPC_PGC_GPU_PUPSCR	0x264
@@ -243,6 +244,7 @@ static int __init imx_gpc_init(struct device_node *node,
 {
 	struct irq_domain *parent_domain, *domain;
 	int i;
+	u32 val;
 
 	if (!parent) {
 		pr_err("%s: no parent, giving up\n", node->full_name);
@@ -271,6 +273,12 @@ static int __init imx_gpc_init(struct device_node *node,
 	for (i = 0; i < IMR_NUM; i++)
 		writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
 
+	/* clear the L2_PGE bit on i.MX6SLL */
+	if (cpu_is_imx6sll()) {
+		val = readl_relaxed(gpc_base + GPC_CNTR);
+		val &= ~(1 << GPC_CNTR_L2_PGE);
+		writel_relaxed(val, gpc_base + GPC_CNTR);
+	}
 	/*
 	 * Clear the OF_POPULATED flag set in of_irq_init so that
 	 * later the GPC power domain driver will not be skipped.
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0408490..462ed9c 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -17,6 +17,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "hardware.h"
 #include "cpuidle.h"
 
 static void __init imx6sl_fec_init(void)
@@ -54,7 +55,8 @@ static void __init imx6sl_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
-	imx6sl_fec_init();
+	if (cpu_is_imx6sl())
+		imx6sl_fec_init();
 	imx_anatop_init();
 	imx6sl_pm_init();
 }
@@ -66,11 +68,15 @@ static void __init imx6sl_init_irq(void)
 	imx_init_l2cache();
 	imx_src_init();
 	irqchip_init();
-	imx6_pm_ccm_init("fsl,imx6sl-ccm");
+	if (cpu_is_imx6sl())
+		imx6_pm_ccm_init("fsl,imx6sl-ccm");
+	else
+		imx6_pm_ccm_init("fsl,imx6sll-ccm");
 }
 
 static const char * const imx6sl_dt_compat[] __initconst = {
 	"fsl,imx6sl",
+	"fsl,imx6sll",
 	NULL,
 };
 
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 34f2ff6..e047611 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -39,6 +39,7 @@
 #define MXC_CPU_IMX6SX		0x62
 #define MXC_CPU_IMX6Q		0x63
 #define MXC_CPU_IMX6UL		0x64
+#define MXC_CPU_IMX6SLL		0x67
 #define MXC_CPU_IMX7D		0x72
 
 #define IMX_DDR_TYPE_LPDDR2		1
@@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void)
 	return __mxc_cpu_type == MXC_CPU_IMX6UL;
 }
 
+static inline bool cpu_is_imx6sll(void)
+{
+	return __mxc_cpu_type == MXC_CPU_IMX6SLL;
+}
+
 static inline bool cpu_is_imx6q(void)
 {
 	return __mxc_cpu_type == MXC_CPU_IMX6Q;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 00/12] Add basic code support for imx6sll
From: Bai Ping @ 2016-12-27  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

The i.MX 6SoloLiteLite application processors are NXP's
latest additions to a growing family of multimedia-focused
products offering high-performance processing optimized for
lowest power consumption. The i.MX 6SoloLiteLite processors
feature NXP's advanced implementation of the ARM Cortex-A9 core,
which can be interfaced with LPDDR3 and LPDDR2 DRAM memory devices.

i.MX6SLL is a new SOC of the i.MX6 family, shares many common modules,
so most of the MSL code can be resued from i.MX6 serious SOC.


change for V2:
    -  address comments in dts and dtsi from Fabio.
    -  split the doc update into two patch, fix typo.
    -  address comments in clock driver, add necessary 'const'qualifier.

Bai Ping (12):
  ARM: imx: Add basic msl support for imx6sll
  driver: clocksource: add gpt timer for imx6sll
  Document: dt: binding: imx: update clock doc for imx6sll
  driver: clk: imx: Add clock driver for imx6sll
  Document: dt: binding: imx: update pinctrl doc for imx6sll
  driver: pinctrl: imx: Add pinctrl driver support for imx6sll
  ARM: dts: imx: Add basic dtsi for imx6sll
  ARM: dts: imx: Add imx6sll EVK board dts support
  ARM: debug: Add low level debug support for imx6sll
  ARM: imx: Add suspend/resume support for imx6sll
  ARM: imx: correct i.mx6sll dram io low power mode
  ARM: configs: enable imx6sll support in defconfig

 .../devicetree/bindings/clock/imx6sll-clock.txt    |  37 +
 .../bindings/pinctrl/fsl,imx6sll-pinctrl.txt       |  37 +
 arch/arm/Kconfig.debug                             |   9 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/imx6sll-evk.dts                  | 474 +++++++++++
 arch/arm/boot/dts/imx6sll-pinfunc.h                | 882 +++++++++++++++++++++
 arch/arm/boot/dts/imx6sll.dtsi                     | 843 ++++++++++++++++++++
 arch/arm/configs/imx_v6_v7_defconfig               |   1 +
 arch/arm/include/debug/imx-uart.h                  |  10 +
 arch/arm/mach-imx/Kconfig                          |   8 +
 arch/arm/mach-imx/Makefile                         |   1 +
 arch/arm/mach-imx/cpu.c                            |   3 +
 arch/arm/mach-imx/cpuidle-imx6sl.c                 |   7 +-
 arch/arm/mach-imx/gpc.c                            |   8 +
 arch/arm/mach-imx/mach-imx6sl.c                    |  10 +-
 arch/arm/mach-imx/mxc.h                            |   6 +
 arch/arm/mach-imx/pm-imx6.c                        |  49 +-
 arch/arm/mach-imx/suspend-imx6.S                   |  29 +-
 drivers/clk/imx/Makefile                           |   1 +
 drivers/clk/imx/clk-imx6sll.c                      | 369 +++++++++
 drivers/clocksource/timer-imx-gpt.c                |   1 +
 drivers/pinctrl/freescale/Kconfig                  |   7 +
 drivers/pinctrl/freescale/Makefile                 |   1 +
 drivers/pinctrl/freescale/pinctrl-imx6sll.c        | 385 +++++++++
 include/dt-bindings/clock/imx6sll-clock.h          | 204 +++++
 25 files changed, 3352 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6sll-clock.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6sll-pinctrl.txt
 create mode 100644 arch/arm/boot/dts/imx6sll-evk.dts
 create mode 100644 arch/arm/boot/dts/imx6sll-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imx6sll.dtsi
 create mode 100644 drivers/clk/imx/clk-imx6sll.c
 create mode 100644 drivers/pinctrl/freescale/pinctrl-imx6sll.c
 create mode 100644 include/dt-bindings/clock/imx6sll-clock.h

-- 
1.9.1

^ permalink raw reply

* [PATCH 9/9] irqchip/ls-scfg-msi: add MSI affinity support
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

For LS1046a and LS1043a v1.1, the MSI controller has 4 MSIRs and 4
CPUs. A GIC SPI interrupt of MSIR can be associated with a CPU.
When changing MSI interrupt affinity, this MSI will be moved to the
corresponding MSIR and MSI message data will be changed according to
MSIR. when requesting a MSI, the bits of all 4 MSIR will be reserved.
The parameter 'msi_affinity_flag' is provide to change this mode.
"lsmsi=no-affinity" will disable affinity, all MSI can only be
associated with CPU 0.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 drivers/irqchip/irq-ls-scfg-msi.c | 75 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 70 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index dc19569..753fe39 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -40,6 +40,7 @@ struct ls_scfg_msir {
 	unsigned int gic_irq;
 	unsigned int bit_start;
 	unsigned int bit_end;
+	unsigned int srs; /* Shared interrupt register select */
 	void __iomem *reg;
 };
 
@@ -70,6 +71,19 @@ struct ls_scfg_msi {
 	.chip	= &ls_scfg_msi_irq_chip,
 };
 
+static int msi_affinity_flag = 1;
+
+static int __init early_parse_ls_scfg_msi(char *p)
+{
+	if (p && strncmp(p, "no-affinity", 11) == 0)
+		msi_affinity_flag = 0;
+	else
+		msi_affinity_flag = 1;
+
+	return 0;
+}
+early_param("lsmsi", early_parse_ls_scfg_msi);
+
 static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(data);
@@ -77,12 +91,43 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 	msg->address_hi = upper_32_bits(msi_data->msiir_addr);
 	msg->address_lo = lower_32_bits(msi_data->msiir_addr);
 	msg->data = data->hwirq;
+
+	if (msi_affinity_flag) {
+		u32 msir_index;
+
+		msir_index = cpumask_first(data->common->affinity);
+		if (msir_index >= msi_data->msir_num)
+			msir_index = 0;
+
+		msg->data |= msir_index;
+	}
 }
 
 static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
 				    const struct cpumask *mask, bool force)
 {
-	return -EINVAL;
+	struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(irq_data);
+	u32 cpu;
+
+	if (!msi_affinity_flag)
+		return -EINVAL;
+
+	if (!force)
+		cpu = cpumask_any_and(mask, cpu_online_mask);
+	else
+		cpu = cpumask_first(mask);
+
+	if (cpu >= msi_data->msir_num)
+		return -EINVAL;
+
+	if (msi_data->msir[cpu].gic_irq <= 0) {
+		pr_warn("cannot bind the irq to cpu%d\n", cpu);
+		return -EINVAL;
+	}
+
+	cpumask_copy(irq_data->common->affinity, mask);
+
+	return IRQ_SET_MASK_OK;
 }
 
 static struct irq_chip ls_scfg_msi_parent_chip = {
@@ -158,7 +203,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
 
 	for_each_set_bit_from(pos, &val, size) {
 		hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
-			msir->index;
+			msir->srs;
 		virq = irq_find_mapping(msi_data->parent, hwirq);
 		if (virq)
 			generic_handle_irq(virq);
@@ -221,10 +266,19 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
 					 ls_scfg_msi_irq_handler,
 					 msir);
 
+	if (msi_affinity_flag) {
+		/* Associate MSIR interrupt to the cpu */
+		irq_set_affinity(msir->gic_irq, get_cpu_mask(index));
+		msir->srs = 0; /* This value is determined by the CPU */
+	} else
+		msir->srs = index;
+
 	/* Release the hwirqs corresponding to this MSIR */
-	for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
-		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
-		bitmap_clear(msi_data->used, hwirq, 1);
+	if (!msi_affinity_flag || msir->index == 0) {
+		for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
+			hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+			bitmap_clear(msi_data->used, hwirq, 1);
+		}
 	}
 
 	return 0;
@@ -316,6 +370,17 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
 	bitmap_set(msi_data->used, 0, msi_data->irqs_num);
 
 	msi_data->msir_num = of_irq_count(pdev->dev.of_node);
+
+	if (msi_affinity_flag) {
+		u32 cpu_num;
+
+		cpu_num = num_possible_cpus();
+		if (msi_data->msir_num >= cpu_num)
+			msi_data->msir_num = cpu_num;
+		else
+			msi_affinity_flag = 0;
+	}
+
 	msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
 				      sizeof(*msi_data->msir),
 				      GFP_KERNEL);
-- 
1.9.1

^ permalink raw reply related

* [PATCH 8/9] irqchip/ls-scfg-msi: add LS1043a v1.1 MSI support
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

A MSI controller of LS1043a v1.0 only includes one MSIR and
is assigned one GIC interrupt. In order to support affinity,
LS1043a v1.1 MSI is assigned 4 MSIRs and 4 GIC interrupts.
But the MSIR has the different offset and only supports 8 MSIs.
The bits between variable bit_start and bit_end in structure
ls_scfg_msir are used to show 8 MSI interrupts. msir_irqs and
msir_base are added to describe the difference of MSI between
LS1043a v1.1 and other SoCs.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 .../interrupt-controller/fsl,ls-scfg-msi.txt       |  1 +
 drivers/irqchip/irq-ls-scfg-msi.c                  | 45 +++++++++++++++++++---
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
index dde4552..49ccabb 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -7,6 +7,7 @@ Required properties:
               "fsl,ls1021a-msi"
               "fsl,ls1043a-msi"
               "fsl,ls1046a-msi"
+              "fsl,ls1043a-v1.1-msi"
 - msi-controller: indicates that this is a PCIe MSI controller node
 - reg: physical base address of the controller and length of memory mapped.
 - interrupts: an interrupt to the parent interrupt controller.
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 67547bd..dc19569 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -25,14 +25,21 @@
 #define MSI_IRQS_PER_MSIR	32
 #define MSI_MSIR_OFFSET		4
 
+#define MSI_LS1043V1_1_IRQS_PER_MSIR	8
+#define MSI_LS1043V1_1_MSIR_OFFSET	0x10
+
 struct ls_scfg_msi_cfg {
 	u32 ibs_shift; /* Shift of interrupt bit select */
+	u32 msir_irqs; /* The irq number per MSIR */
+	u32 msir_base; /* The base address of MSIR */
 };
 
 struct ls_scfg_msir {
 	struct ls_scfg_msi *msi_data;
 	unsigned int index;
 	unsigned int gic_irq;
+	unsigned int bit_start;
+	unsigned int bit_end;
 	void __iomem *reg;
 };
 
@@ -140,13 +147,18 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
 	struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
 	struct ls_scfg_msi *msi_data = msir->msi_data;
 	unsigned long val;
-	int pos, virq, hwirq;
+	int pos, size, virq, hwirq;
 
 	chained_irq_enter(irq_desc_get_chip(desc), desc);
 
 	val = ioread32be(msir->reg);
-	for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) {
-		hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index;
+
+	pos = msir->bit_start;
+	size = msir->bit_end + 1;
+
+	for_each_set_bit_from(pos, &val, size) {
+		hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
+			msir->index;
 		virq = irq_find_mapping(msi_data->parent, hwirq);
 		if (virq)
 			generic_handle_irq(virq);
@@ -193,14 +205,24 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
 	msir->index = index;
 	msir->msi_data = msi_data;
 	msir->gic_irq = virq;
-	msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index;
+	msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index;
+
+	if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) {
+		msir->bit_start = 32 - ((msir->index + 1) *
+				  MSI_LS1043V1_1_IRQS_PER_MSIR);
+		msir->bit_end = msir->bit_start +
+				MSI_LS1043V1_1_IRQS_PER_MSIR - 1;
+	} else {
+		msir->bit_start = 0;
+		msir->bit_end = msi_data->cfg->msir_irqs - 1;
+	}
 
 	irq_set_chained_handler_and_data(msir->gic_irq,
 					 ls_scfg_msi_irq_handler,
 					 msir);
 
 	/* Release the hwirqs corresponding to this MSIR */
-	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
+	for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
 		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
 		bitmap_clear(msi_data->used, hwirq, 1);
 	}
@@ -216,7 +238,7 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
 	if (msir->gic_irq > 0)
 		irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL);
 
-	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
+	for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
 		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
 		bitmap_set(msi_data->used, hwirq, 1);
 	}
@@ -226,15 +248,26 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
 
 static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
 	.ibs_shift = 3,
+	.msir_irqs = MSI_IRQS_PER_MSIR,
+	.msir_base = MSI_MSIR_OFFSET,
 };
 
 static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
 	.ibs_shift = 2,
+	.msir_irqs = MSI_IRQS_PER_MSIR,
+	.msir_base = MSI_MSIR_OFFSET,
+};
+
+static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = {
+	.ibs_shift = 2,
+	.msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR,
+	.msir_base = MSI_LS1043V1_1_MSIR_OFFSET,
 };
 
 static const struct of_device_id ls_scfg_msi_id[] = {
 	{ .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
 	{ .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
+	{ .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg },
 	{ .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },
 	{},
 };
-- 
1.9.1

^ permalink raw reply related

* [PATCH 7/9] irqchip/ls-scfg-msi: add LS1046a MSI support
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

LS1046a includes 4 MSIRs, each MSIR is assigned a dedicate GIC
SPI interrupt and provides 32 MSI interrupts. Compared to previous
MSI, LS1046a's IBS(interrupt bit select) shift is changed to 2 and
total MSI interrupt number is changed to 128.

The patch adds structure 'ls_scfg_msir' to describe MSIR setting and
'ibs_shift' to store the different value between the SoCs.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 .../interrupt-controller/fsl,ls-scfg-msi.txt       |   2 +-
 drivers/irqchip/irq-ls-scfg-msi.c                  | 161 ++++++++++++++++-----
 2 files changed, 127 insertions(+), 36 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
index 54597b0..dde4552 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -6,7 +6,7 @@ Required properties:
 	      Layerscape PCIe MSI controller block such as:
               "fsl,ls1021a-msi"
               "fsl,ls1043a-msi"
-	      "fsl,ls1046a-msi"
+              "fsl,ls1046a-msi"
 - msi-controller: indicates that this is a PCIe MSI controller node
 - reg: physical base address of the controller and length of memory mapped.
 - interrupts: an interrupt to the parent interrupt controller.
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index cef67cc..67547bd 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -17,13 +17,24 @@
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
+#include <linux/of_irq.h>
 #include <linux/of_pci.h>
 #include <linux/of_platform.h>
 #include <linux/spinlock.h>
 
-#define MSI_MAX_IRQS	32
-#define MSI_IBS_SHIFT	3
-#define MSIR		4
+#define MSI_IRQS_PER_MSIR	32
+#define MSI_MSIR_OFFSET		4
+
+struct ls_scfg_msi_cfg {
+	u32 ibs_shift; /* Shift of interrupt bit select */
+};
+
+struct ls_scfg_msir {
+	struct ls_scfg_msi *msi_data;
+	unsigned int index;
+	unsigned int gic_irq;
+	void __iomem *reg;
+};
 
 struct ls_scfg_msi {
 	spinlock_t		lock;
@@ -32,8 +43,11 @@ struct ls_scfg_msi {
 	struct irq_domain	*msi_domain;
 	void __iomem		*regs;
 	phys_addr_t		msiir_addr;
-	int			irq;
-	DECLARE_BITMAP(used, MSI_MAX_IRQS);
+	struct ls_scfg_msi_cfg	*cfg;
+	u32			msir_num;
+	struct ls_scfg_msir	*msir;
+	u32			irqs_num;
+	unsigned long		*used;
 };
 
 static struct irq_chip ls_scfg_msi_irq_chip = {
@@ -55,7 +69,7 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 
 	msg->address_hi = upper_32_bits(msi_data->msiir_addr);
 	msg->address_lo = lower_32_bits(msi_data->msiir_addr);
-	msg->data = data->hwirq << MSI_IBS_SHIFT;
+	msg->data = data->hwirq;
 }
 
 static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
@@ -81,8 +95,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain,
 	WARN_ON(nr_irqs != 1);
 
 	spin_lock(&msi_data->lock);
-	pos = find_first_zero_bit(msi_data->used, MSI_MAX_IRQS);
-	if (pos < MSI_MAX_IRQS)
+	pos = find_first_zero_bit(msi_data->used, msi_data->irqs_num);
+	if (pos < msi_data->irqs_num)
 		__set_bit(pos, msi_data->used);
 	else
 		err = -ENOSPC;
@@ -106,7 +120,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
 	int pos;
 
 	pos = d->hwirq;
-	if (pos < 0 || pos >= MSI_MAX_IRQS) {
+	if (pos < 0 || pos >= msi_data->irqs_num) {
 		pr_err("failed to teardown msi. Invalid hwirq %d\n", pos);
 		return;
 	}
@@ -123,15 +137,17 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain,
 
 static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
 {
-	struct ls_scfg_msi *msi_data = irq_desc_get_handler_data(desc);
+	struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
+	struct ls_scfg_msi *msi_data = msir->msi_data;
 	unsigned long val;
-	int pos, virq;
+	int pos, virq, hwirq;
 
 	chained_irq_enter(irq_desc_get_chip(desc), desc);
 
-	val = ioread32be(msi_data->regs + MSIR);
-	for_each_set_bit(pos, &val, MSI_MAX_IRQS) {
-		virq = irq_find_mapping(msi_data->parent, (31 - pos));
+	val = ioread32be(msir->reg);
+	for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) {
+		hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index;
+		virq = irq_find_mapping(msi_data->parent, hwirq);
 		if (virq)
 			generic_handle_irq(virq);
 	}
@@ -143,7 +159,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
 {
 	/* Initialize MSI domain parent */
 	msi_data->parent = irq_domain_add_linear(NULL,
-						 MSI_MAX_IRQS,
+						 msi_data->irqs_num,
 						 &ls_scfg_msi_domain_ops,
 						 msi_data);
 	if (!msi_data->parent) {
@@ -164,16 +180,83 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
 	return 0;
 }
 
+static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
+{
+	struct ls_scfg_msir *msir;
+	int virq, i, hwirq;
+
+	virq = platform_get_irq(msi_data->pdev, index);
+	if (virq <= 0)
+		return -ENODEV;
+
+	msir = &msi_data->msir[index];
+	msir->index = index;
+	msir->msi_data = msi_data;
+	msir->gic_irq = virq;
+	msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index;
+
+	irq_set_chained_handler_and_data(msir->gic_irq,
+					 ls_scfg_msi_irq_handler,
+					 msir);
+
+	/* Release the hwirqs corresponding to this MSIR */
+	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
+		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+		bitmap_clear(msi_data->used, hwirq, 1);
+	}
+
+	return 0;
+}
+
+static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
+{
+	struct ls_scfg_msi *msi_data = msir->msi_data;
+	int i, hwirq;
+
+	if (msir->gic_irq > 0)
+		irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL);
+
+	for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
+		hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+		bitmap_set(msi_data->used, hwirq, 1);
+	}
+
+	return 0;
+}
+
+static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
+	.ibs_shift = 3,
+};
+
+static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
+	.ibs_shift = 2,
+};
+
+static const struct of_device_id ls_scfg_msi_id[] = {
+	{ .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
+	{ .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
+	{ .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ls_scfg_msi_id);
+
 static int ls_scfg_msi_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *match;
 	struct ls_scfg_msi *msi_data;
 	struct resource *res;
-	int ret;
+	int i, ret;
+
+	match = of_match_device(ls_scfg_msi_id, &pdev->dev);
+	if (!match)
+		return -ENODEV;
 
 	msi_data = devm_kzalloc(&pdev->dev, sizeof(*msi_data), GFP_KERNEL);
 	if (!msi_data)
 		return -ENOMEM;
 
+	msi_data->cfg = (struct ls_scfg_msi_cfg *) match->data;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	msi_data->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(msi_data->regs)) {
@@ -182,23 +265,37 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
 	}
 	msi_data->msiir_addr = res->start;
 
-	msi_data->irq = platform_get_irq(pdev, 0);
-	if (msi_data->irq <= 0) {
-		dev_err(&pdev->dev, "failed to get MSI irq\n");
-		return -ENODEV;
-	}
-
 	msi_data->pdev = pdev;
 	spin_lock_init(&msi_data->lock);
 
+	msi_data->irqs_num = MSI_IRQS_PER_MSIR *
+			     (1 << msi_data->cfg->ibs_shift);
+	msi_data->used = devm_kcalloc(&pdev->dev,
+				    BITS_TO_LONGS(msi_data->irqs_num),
+				    sizeof(*msi_data->used),
+				    GFP_KERNEL);
+	if (!msi_data->used)
+		return -ENOMEM;
+	/*
+	 * Reserve all the hwirqs
+	 * The available hwirqs will be released in ls1_msi_setup_hwirq()
+	 */
+	bitmap_set(msi_data->used, 0, msi_data->irqs_num);
+
+	msi_data->msir_num = of_irq_count(pdev->dev.of_node);
+	msi_data->msir = devm_kcalloc(&pdev->dev, msi_data->msir_num,
+				      sizeof(*msi_data->msir),
+				      GFP_KERNEL);
+	if (!msi_data->msir)
+		return -ENOMEM;
+
+	for (i = 0; i < msi_data->msir_num; i++)
+		ls_scfg_msi_setup_hwirq(msi_data, i);
+
 	ret = ls_scfg_msi_domains_init(msi_data);
 	if (ret)
 		return ret;
 
-	irq_set_chained_handler_and_data(msi_data->irq,
-					 ls_scfg_msi_irq_handler,
-					 msi_data);
-
 	platform_set_drvdata(pdev, msi_data);
 
 	return 0;
@@ -207,8 +304,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev)
 static int ls_scfg_msi_remove(struct platform_device *pdev)
 {
 	struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev);
+	int i;
 
-	irq_set_chained_handler_and_data(msi_data->irq, NULL, NULL);
+	for (i = 0; i < msi_data->msir_num; i++)
+		ls_scfg_msi_teardown_hwirq(&msi_data->msir[i]);
 
 	irq_domain_remove(msi_data->msi_domain);
 	irq_domain_remove(msi_data->parent);
@@ -218,14 +317,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct of_device_id ls_scfg_msi_id[] = {
-	{ .compatible = "fsl,1s1021a-msi", }, /* a typo */
-	{ .compatible = "fsl,1s1043a-msi", }, /* a typo */
-	{ .compatible = "fsl,ls1021a-msi", },
-	{ .compatible = "fsl,ls1043a-msi", },
-	{},
-};
-
 static struct platform_driver ls_scfg_msi_driver = {
 	.driver = {
 		.name = "ls-scfg-msi",
-- 
1.9.1

^ permalink raw reply related

* [PATCH 6/9] arm64: dts: ls1046a: add MSI dts node
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

LS1046a includes 3 MSI controllers.
Each controller supports 128 interrupts.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 .../interrupt-controller/fsl,ls-scfg-msi.txt       |  1 +
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi     | 31 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
index 2755cd1..54597b0 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -6,6 +6,7 @@ Required properties:
 	      Layerscape PCIe MSI controller block such as:
               "fsl,ls1021a-msi"
               "fsl,ls1043a-msi"
+	      "fsl,ls1046a-msi"
 - msi-controller: indicates that this is a PCIe MSI controller node
 - reg: physical base address of the controller and length of memory mapped.
 - interrupts: an interrupt to the parent interrupt controller.
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 38806ca..49dbafc 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -511,5 +511,36 @@
 			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clockgen 4 1>;
 		};
+
+		msi1: msi-controller at 1580000 {
+			compatible = "fsl,ls1046a-msi";
+			msi-controller;
+			reg = <0x0 0x1580000 0x0 0x10000>;
+			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		msi2: msi-controller at 1590000 {
+			compatible = "fsl,ls1046a-msi";
+			msi-controller;
+			reg = <0x0 0x1590000 0x0 0x10000>;
+			interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		msi3: msi-controller at 15a0000 {
+			compatible = "fsl,ls1046a-msi";
+			msi-controller;
+			reg = <0x0 0x15a0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
 	};
 };
-- 
1.9.1

^ permalink raw reply related

* [PATCH 5/9] arm64: dts: ls1043a: share all MSIs
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

In order to maximize the use of MSI, a PCIe controller will share
all MSI controllers. The patch changes "msi-parent" to refer to all
MSI controller dts nodes.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index 692fc35..3947220 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -625,7 +625,7 @@
 			bus-range = <0x0 0xff>;
 			ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000   /* downstream I/O */
 				  0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
-			msi-parent = <&msi1>;
+			msi-parent = <&msi1>, <&msi2>, <&msi3>;
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0000 0 0 1 &gic 0 110 0x4>,
@@ -650,7 +650,7 @@
 			bus-range = <0x0 0xff>;
 			ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000   /* downstream I/O */
 				  0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
-			msi-parent = <&msi2>;
+			msi-parent = <&msi1>, <&msi2>, <&msi3>;
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0000 0 0 1 &gic 0 120  0x4>,
@@ -675,7 +675,7 @@
 			bus-range = <0x0 0xff>;
 			ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000   /* downstream I/O */
 				  0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
-			msi-parent = <&msi3>;
+			msi-parent = <&msi1>, <&msi2>, <&msi3>;
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0000 0 0 1 &gic 0 154 0x4>,
-- 
1.9.1

^ permalink raw reply related

* [PATCH 4/9] arm: dts: ls1021a: share all MSIs
From: Minghuan Lian @ 2016-12-27  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

In order to maximize the use of MSI, a PCIe controller will share
all MSI controllers. The patch changes msi-parent to refer to all
MSI controller dts nodes.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 6651938..1c82024 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -723,7 +723,7 @@
 			bus-range = <0x0 0xff>;
 			ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000   /* downstream I/O */
 				  0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
-			msi-parent = <&msi1>;
+			msi-parent = <&msi1>, <&msi2>;
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0000 0 0 1 &gic GIC_SPI 91  IRQ_TYPE_LEVEL_HIGH>,
@@ -746,7 +746,7 @@
 			bus-range = <0x0 0xff>;
 			ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000   /* downstream I/O */
 				  0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
-			msi-parent = <&msi2>;
+			msi-parent = <&msi1>, <&msi2>;
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0000 0 0 1 &gic GIC_SPI 92  IRQ_TYPE_LEVEL_HIGH>,
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/9] arm64: dts: ls1043a: fix typo of MSI compatible string
From: Minghuan Lian @ 2016-12-27  9:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

"1" should be replaced by "l". This is a typo.
The patch is to fix it.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index ec13a6e..692fc35 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -589,21 +589,21 @@
 		};
 
 		msi1: msi-controller1 at 1571000 {
-			compatible = "fsl,1s1043a-msi";
+			compatible = "fsl,ls1043a-msi";
 			reg = <0x0 0x1571000 0x0 0x8>;
 			msi-controller;
 			interrupts = <0 116 0x4>;
 		};
 
 		msi2: msi-controller2 at 1572000 {
-			compatible = "fsl,1s1043a-msi";
+			compatible = "fsl,ls1043a-msi";
 			reg = <0x0 0x1572000 0x0 0x8>;
 			msi-controller;
 			interrupts = <0 126 0x4>;
 		};
 
 		msi3: msi-controller3 at 1573000 {
-			compatible = "fsl,1s1043a-msi";
+			compatible = "fsl,ls1043a-msi";
 			reg = <0x0 0x1573000 0x0 0x8>;
 			msi-controller;
 			interrupts = <0 160 0x4>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/9] arm: dts: ls1021a: fix typo of MSI compatible string
From: Minghuan Lian @ 2016-12-27  9:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482829985-24421-1-git-send-email-Minghuan.Lian@nxp.com>

"1" should be replaced by "l". This is a typo.
The patch is to fix it.

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 282d854..6651938 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -122,14 +122,14 @@
 		};
 
 		msi1: msi-controller at 1570e00 {
-			compatible = "fsl,1s1021a-msi";
+			compatible = "fsl,ls1021a-msi";
 			reg = <0x0 0x1570e00 0x0 0x8>;
 			msi-controller;
 			interrupts =  <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		msi2: msi-controller at 1570e08 {
-			compatible = "fsl,1s1021a-msi";
+			compatible = "fsl,ls1021a-msi";
 			reg = <0x0 0x1570e08 0x0 0x8>;
 			msi-controller;
 			interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/9] irqchip/ls-scfg-msi: fix typo of MSI compatible strings
From: Minghuan Lian @ 2016-12-27  9:12 UTC (permalink / raw)
  To: linux-arm-kernel

The patch is to fix typo of the Layerscape SCFG MSI dts compatible
strings. "1" is replaced by "l".

Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
---
 .../devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt    | 6 +++---
 drivers/irqchip/irq-ls-scfg-msi.c                                   | 6 ++++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
index 9e38949..2755cd1 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
@@ -4,8 +4,8 @@ Required properties:
 
 - compatible: should be "fsl,<soc-name>-msi" to identify
 	      Layerscape PCIe MSI controller block such as:
-              "fsl,1s1021a-msi"
-              "fsl,1s1043a-msi"
+              "fsl,ls1021a-msi"
+              "fsl,ls1043a-msi"
 - msi-controller: indicates that this is a PCIe MSI controller node
 - reg: physical base address of the controller and length of memory mapped.
 - interrupts: an interrupt to the parent interrupt controller.
@@ -23,7 +23,7 @@ MSI controller node
 Examples:
 
 	msi1: msi-controller at 1571000 {
-		compatible = "fsl,1s1043a-msi";
+		compatible = "fsl,ls1043a-msi";
 		reg = <0x0 0x1571000 0x0 0x8>,
 		msi-controller;
 		interrupts = <0 116 0x4>;
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 02cca74c..cef67cc 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -219,8 +219,10 @@ static int ls_scfg_msi_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id ls_scfg_msi_id[] = {
-	{ .compatible = "fsl,1s1021a-msi", },
-	{ .compatible = "fsl,1s1043a-msi", },
+	{ .compatible = "fsl,1s1021a-msi", }, /* a typo */
+	{ .compatible = "fsl,1s1043a-msi", }, /* a typo */
+	{ .compatible = "fsl,ls1021a-msi", },
+	{ .compatible = "fsl,ls1043a-msi", },
 	{},
 };
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH] crypto: arm64/aes: reimplement bit-sliced ARM/NEON implementation for arm64
From: Herbert Xu @ 2016-12-27  9:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481564758-7275-1-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 12, 2016 at 05:45:58PM +0000, Ard Biesheuvel wrote:
>
> +	.chunksize		= 8 * AES_BLOCK_SIZE,

Same comment as to the previous patches regarding chunksize.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [PATCH v2 2/3] crypto: arm64/chacha20 - implement NEON version based on SSE3 code
From: Herbert Xu @ 2016-12-27  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481294033-23508-3-git-send-email-ard.biesheuvel@linaro.org>

On Fri, Dec 09, 2016 at 02:33:52PM +0000, Ard Biesheuvel wrote:
>
> +	.chunksize		= 4 * CHACHA20_BLOCK_SIZE,

This should use a new attribute specific to the walk interface.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [PATCH] crypto: arm/aes-neonbs - process 8 blocks in parallel if we can
From: Herbert Xu @ 2016-12-27  8:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481291246-20216-1-git-send-email-ard.biesheuvel@linaro.org>

On Fri, Dec 09, 2016 at 01:47:26PM +0000, Ard Biesheuvel wrote:
> The bit-sliced NEON implementation of AES only performs optimally if
> it can process 8 blocks of input in parallel. This is due to the nature
> of bit slicing, where the n-th bit of each byte of AES state of each input
> block is collected into NEON register 'n', for registers q0 - q7.
> 
> This implies that the amount of work for the transform is fixed,
> regardless of whether we are handling just one block or 8 in parallel.
> 
> So let's try a bit harder to iterate over the input in suitably sized
> chunks, by increasing the chunksize to 8 * AES_BLOCK_SIZE, and tweaking
> the loops to only process multiples of the chunk size, unless we are
> handling the last chunk in the input stream.
> 
> Note that the skcipher walk API guarantees that a step in the walk never
> returns less that 'chunksize' bytes if there are at least that many bytes
> of input still available. However, it does *not* guarantee that those steps
> produce an exact multiple of the chunk size.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

I like this patch.  However, I had different plans for the chunksize
attribute.  It's primarily meant to be a hint to the upper layer
in case it does partial updates.  It's meant to provide the minimum
number of bytes a partial update can carry without screwing up
subsequent updates.

It just happens to be the same value that we were using during
an skcipher walk.

So I think for your case we should add a new attribute, perhaps
walk_chunksize or walksize, which doesn't need to be exported to
the outside at all and can then be used by the walk interface.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [PATCH 0/9] Runtime PM for Exynos pin controller driver
From: Marek Szyprowski @ 2016-12-27  8:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANAwSgRQuoriU923XT1B_0CVX2rzOR+8j2YHLMYRUu3gGySEBw@mail.gmail.com>

Hi Anand,


On 2016-12-24 11:10, Anand Moon wrote:
> Hi Marek
>
> On 23 December 2016 at 17:54, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> Hello,
>>
>> This patchset is a next step to add support for audio power domain on
>> Exynos5 SoCs.
>>
>> Audio power domain on Exynos5 SoCs contains following hardware modules:
>> 1. clock controller
>> 2. pin controller
>> 3. PL330 DMA controller
>> 4. I2S audio controller
>>
>> Till now it was assumed that pin controller is located in the "always on"
>> power domain and lacked runtime power management. This patch finally
>> removes such assumption and adds runtime pm support and awareness to this
>> driver. To achieve this, some changes in the Exynos platform support code
>> were needed, like moving pad retention control to the pin controller driver.
>> Some cleanup to the pin controller driver has been also done while changing
>> the code. This new feature requires some additional information in the
>> device tree, what is handled by patches 1,2 and 9.
>>
>> Please note that patches are ordered in such a way that the changes can be
>> bisected, so the properties are added to dts before the code requiring them.
>>
>> The other patches related to enabling full support for audio power domain
>> can be found here:
>> 1. PL330 ADMA controller non-irqsafe runtime PM:
>>     https://www.spinics.net/lists/arm-kernel/msg550008.html
>> 2. Runtime PM for clock controllers (Exynos Audio subsystem will be added
>>     in v4 soon): https://www.spinics.net/lists/arm-kernel/msg538122.html
>>
>> Patches are based on linux-next from 2016.12.22.
>>
>> Best regards
>> Marek Szyprowski
>> Samsung R&D Institute Poland
>>
>>
>> Patch summary:
>>
>> Marek Szyprowski (9):
>>    ARM: dts: exynos: Add PMU syscon to pinctrl nodes
>>    ARM: dts: exynos: Add pinctrl sleep state for 542x i2s module
>>    pinctrl: samsung: Remove dead code
>>    pinctrl: samsung: Use generic of_device_get_match_data helper
>>    pinctrl: samsung: Move retention control from mach-exynos to the
>>      pinctrl driver
>>    pinctrl: samsung: Replace syscore ops with standard platform device
>>      pm_ops
>>    pinctrl: samsung: Add property to mark pad state as suitable for power
>>      down
>>    pinctrl: samsung: Add runtime PM support
>>    ARM: dts: exynos: Add audio power domain support to Exynos542x SoCs
>>
>>   .../bindings/pinctrl/samsung-pinctrl.txt           |  12 ++
>>   arch/arm/boot/dts/exynos3250.dtsi                  |   2 +
>>   arch/arm/boot/dts/exynos4210.dtsi                  |   3 +
>>   arch/arm/boot/dts/exynos4x12.dtsi                  |   3 +
>>   arch/arm/boot/dts/exynos5250.dtsi                  |   4 +
>>   arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |  11 ++
>>   arch/arm/boot/dts/exynos5420.dtsi                  |  18 ++-
>>   arch/arm/mach-exynos/suspend.c                     |  64 ---------
>>   drivers/pinctrl/samsung/pinctrl-exynos.c           | 148 +++++++++++++++++++++
>>   drivers/pinctrl/samsung/pinctrl-samsung.c          | 126 ++++++++----------
>>   drivers/pinctrl/samsung/pinctrl-samsung.h          |  15 +++
>>   11 files changed, 271 insertions(+), 135 deletions(-)
>>
> Is their core configuration missing to enable audio through HDMI on
> Odroid Boards.
> I could not get the sound working on Odroid XU4.

Audio support for HDMI on Exynos requires some additional code. We will take
a look at this too.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH v3 3/3] ARM: DT: add power-off support to linkstation lsgl and kuroboxpro
From: Roger Shimizu @ 2016-12-27  7:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161227070611.14852-1-rogershimizu@gmail.com>

A few models of Linkstation / KuroBox has micro-controller which
controls the power (as well as FAN, but not related here), while
others not. So remove the restart-poweroff driver in linkstation
common dtsi file, and specify the proper power driver in dts
of each device.

Devices need micro-controler to power-off:
  - Linkstation LS-GL
  - KuroBox Pro
Device continues using original restart-poweroff driver:
  - Linkstation LS-WTGL

To: Jason Cooper <jason@lakedaemon.net>
To: Andrew Lunn <andrew@lunn.ch>
To: Gregory Clement <gregory.clement@free-electrons.com>
To: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Cc: Ryan Tandy <ryan@nardis.ca>
Cc: linux-pm at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

Reported-by: Ryan Tandy <ryan@nardis.ca>
Tested-by: Ryan Tandy <ryan@nardis.ca>
Signed-off-by: Roger Shimizu <rogershimizu@gmail.com>
---
 arch/arm/boot/dts/orion5x-kuroboxpro.dts         |  8 ++++++++
 arch/arm/boot/dts/orion5x-linkstation-lsgl.dts   | 10 ++++++++++
 arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts |  4 ++++
 arch/arm/boot/dts/orion5x-linkstation.dtsi       |  4 ----
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/orion5x-kuroboxpro.dts b/arch/arm/boot/dts/orion5x-kuroboxpro.dts
index 1a672b098d0b..aba38d802bda 100644
--- a/arch/arm/boot/dts/orion5x-kuroboxpro.dts
+++ b/arch/arm/boot/dts/orion5x-kuroboxpro.dts
@@ -60,6 +60,14 @@
 				 <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
 				 <MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x40000>,
 				 <MBUS_ID(0x01, 0x1e) 0 0xfc000000 0x1000000>;
+
+		internal-regs {
+			power_off {
+				compatible = "linkstation,power-off";
+				reg = <0x12100 0x100>;
+				clocks = <&core_clk 0>;
+			};
+		};
 	};
 
 	memory { /* 128 MB */
diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
index 51dc734cd5b9..370fc17a6dd9 100644
--- a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
+++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
@@ -56,6 +56,16 @@
 	model = "Buffalo Linkstation Pro/Live";
 	compatible = "buffalo,lsgl", "marvell,orion5x-88f5182", "marvell,orion5x";
 
+	soc {
+		internal-regs {
+			power_off {
+				compatible = "linkstation,power-off";
+				reg = <0x12100 0x100>;
+				clocks = <&core_clk 0>;
+			};
+		};
+	};
+
 	memory { /* 128 MB */
 		device_type = "memory";
 		reg = <0x00000000 0x8000000>;
diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
index 0eead400f427..571a71f5b7ad 100644
--- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
+++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
@@ -59,6 +59,10 @@
 		reg = <0x00000000 0x4000000>;
 	};
 
+	restart_poweroff {
+		compatible = "restart-poweroff";
+	};
+
 	gpio_keys {
 		power-on-switch {
 			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi
index ed456ab35fd8..40770a8d4b36 100644
--- a/arch/arm/boot/dts/orion5x-linkstation.dtsi
+++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi
@@ -57,10 +57,6 @@
 				 <MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x40000>;
 	};
 
-	restart_poweroff {
-		compatible = "restart-poweroff";
-	};
-
 	regulators {
 		compatible = "simple-bus";
 		#address-cells = <1>;
-- 
2.11.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox