All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] add initial imx6q support
@ 2011-09-06  9:58 Shawn Guo
  2011-09-06  9:58 ` [PATCH 1/6] arm/imx6q: add device tree source Shawn Guo
                   ` (6 more replies)
  0 siblings, 7 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds the initial support for imx6q, which is a
Cortex-A9 MPCore (4 cores) SoC.

It's based on v3.1-rc4 with the patches below applied.

 * [PATCH v2 0/5] Convert DEBUG_LL UART selection to a Kconfig choice
   http://thread.gmane.org/gmane.linux.ports.arm.kernel/129702

 * [PATCH v4 2/2] ARM: l2x0: Add OF based initialization
   http://article.gmane.org/gmane.linux.kernel/1164401

 * [PATCH 1/7] ARM: l2x0: add empty l2x0_of_init
   http://article.gmane.org/gmane.linux.ports.arm.kernel/130878

 * [RFC PATCH 0/3] Yet another GIC OF binding series
   http://thread.gmane.org/gmane.linux.drivers.devicetree/7226

For suspend/resume support, it needs the following extra patches
applied.

 * [PATCH v2 0/2] make reinitialization of ARM core components possible
   http://thread.gmane.org/gmane.linux.ports.arm.kernel/131356

 * [PATCH v2 0/5] CPU PM notifiers
   http://thread.gmane.org/gmane.linux.ports.arm.kernel/131212/focus=131353

Thanks.

Shawn Guo (6):
      arm/imx6q: add device tree source
      arm/imx6q: add core definitions and low-level debug uart
      arm/imx6q: add core drivers clock, gpc, mmdc and src
      arm/imx6q: add smp and cpu hotplug support
      arm/imx6q: add device tree machine support
      arm/imx6q: add suspend/resume support

 Documentation/devicetree/bindings/arm/fsl.txt |    6 +
 arch/arm/Kconfig                              |    2 +-
 arch/arm/Kconfig.debug                        |    7 +
 arch/arm/Makefile                             |    1 +
 arch/arm/boot/dts/imx6q-sabreauto.dts         |   49 +
 arch/arm/boot/dts/imx6q.dtsi                  |  570 +++++++
 arch/arm/mach-imx/Kconfig                     |   31 +
 arch/arm/mach-imx/Makefile                    |   11 +
 arch/arm/mach-imx/Makefile.boot               |    4 +
 arch/arm/mach-imx/clock-imx6q.c               | 1990 +++++++++++++++++++++++++
 arch/arm/mach-imx/gpc.c                       |  110 ++
 arch/arm/mach-imx/head-v7.S                   |   75 +
 arch/arm/mach-imx/hotplug.c                   |   44 +
 arch/arm/mach-imx/lluart.c                    |   33 +
 arch/arm/mach-imx/localtimer.c                |   64 +
 arch/arm/mach-imx/mach-imx6q.c                |   81 +
 arch/arm/mach-imx/mmdc.c                      |   71 +
 arch/arm/mach-imx/platsmp.c                   |   86 ++
 arch/arm/mach-imx/pm-imx6q.c                  |   63 +
 arch/arm/mach-imx/src.c                       |   52 +
 arch/arm/mm/Kconfig                           |    2 +-
 arch/arm/plat-mxc/Kconfig                     |    5 +
 arch/arm/plat-mxc/include/mach/common.h       |   28 +
 arch/arm/plat-mxc/include/mach/debug-macro.S  |    5 +
 arch/arm/plat-mxc/include/mach/entry-macro.S  |   15 +-
 arch/arm/plat-mxc/include/mach/hardware.h     |    1 +
 arch/arm/plat-mxc/include/mach/irqs.h         |    9 +-
 arch/arm/plat-mxc/include/mach/memory.h       |    3 +
 arch/arm/plat-mxc/include/mach/mx6q.h         |   29 +
 29 files changed, 3441 insertions(+), 6 deletions(-)

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

* [PATCH 1/6] arm/imx6q: add device tree source
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 18:31   ` Arnd Bergmann
  2011-09-06  9:58 ` [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart Shawn Guo
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds device tree source and documentation for imx6q platform.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 Documentation/devicetree/bindings/arm/fsl.txt |    6 +
 arch/arm/boot/dts/imx6q-sabreauto.dts         |   49 +++
 arch/arm/boot/dts/imx6q.dtsi                  |  570 +++++++++++++++++++++++++
 3 files changed, 625 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/fsl.txt
 create mode 100644 arch/arm/boot/dts/imx6q-sabreauto.dts
 create mode 100644 arch/arm/boot/dts/imx6q.dtsi

diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
new file mode 100644
index 0000000..345bfc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -0,0 +1,6 @@
+Freescale i.MX Platforms Device Tree Bindings
+-----------------------------------------------
+
+i.MX6 Quad SABRE Automotive Board
+Required root node properties:
+    - compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
new file mode 100644
index 0000000..2b31ecb
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/dts-v1/;
+/include/ "imx6q.dtsi"
+
+/ {
+	model = "Freescale i.MX6 Quad SABRE Automotive Board";
+	compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
+
+	chosen {
+		bootargs = "console=ttymxc3,115200 root=/dev/mmcblk3p3 rootwait";
+	};
+
+	memory {
+		reg = <0x10000000 0x80000000>;
+	};
+
+	aips-bus at 02100000 { /* AIPS2 */
+		enet at 02188000 {
+			phy-mode = "rgmii";
+			local-mac-address = [00 04 9F 01 1B 61];
+			status = "okay";
+		};
+
+		uart3: uart at 021f0000 { /* UART4 */
+			status = "okay";
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		debug-led {
+			label = "Heartbeat";
+			gpios = <&gpio2 25 0>; /* GPIO3_25 */
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
new file mode 100644
index 0000000..7864ee9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/ "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&intc>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu at 1 {
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu at 2 {
+			compatible = "arm,cortex-a9";
+			reg = <2>;
+			next-level-cache = <&L2>;
+		};
+
+		cpu at 3 {
+			compatible = "arm,cortex-a9";
+			reg = <3>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	intc: interrupt-controller at 00a01000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <2>;
+		#size-cells = <0>;
+		#address-cells = <1>;
+		interrupt-controller;
+		reg = <0x00a01000 0x1000>,
+		      <0x00a00100 0x100>;
+
+		gicppi0: gic-ppi at 0 {
+			compatible = "arm,cortex-a9-gic-ppi";
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			reg = <0>;
+		};
+
+		gicppi1: gic-ppi at 1 {
+			compatible = "arm,cortex-a9-gic-ppi";
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			reg = <1>;
+
+		};
+		gicppi2: gic-ppi at 2 {
+			compatible = "arm,cortex-a9-gic-ppi";
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			reg = <2>;
+		};
+
+		gicppi3: gic-ppi at 3 {
+			compatible = "arm,cortex-a9-gic-ppi";
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			reg = <3>;
+		};
+	};
+
+	timer at 00a00600 {
+		compatible = "arm,smp-twd";
+		reg = <0x00a00600 0x100>;
+		interrupt-parent = <&gicppi0>;
+		interrupts = <29>;
+	};
+
+	L2: l2-cache at 00a02000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x00a02000 0x1000>;
+		interrupts = <124 4>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	aips-bus at 02000000 { /* AIPS1 */
+		compatible = "fsl,aips-bus", "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x02000000 0x100000>;
+		ranges;
+
+		spba-bus at 02000000 {
+			compatible = "fsl,spba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x02000000 0x40000>;
+			ranges;
+
+			spdif at 02004000 {
+				reg = <0x02004000 0x4000>;
+				interrupts = <84 4>;
+			};
+
+			ecspi at 02008000 { /* eCSPI1 */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+				reg = <0x02008000 0x4000>;
+				interrupts = <63 4>;
+				status = "disabled";
+			};
+
+			ecspi at 0200c000 { /* eCSPI2 */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+				reg = <0x0200c000 0x4000>;
+				interrupts = <64 4>;
+				status = "disabled";
+			};
+
+			ecspi at 02010000 { /* eCSPI3 */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+				reg = <0x02010000 0x4000>;
+				interrupts = <65 4>;
+				status = "disabled";
+			};
+
+			ecspi at 02014000 { /* eCSPI4 */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+				reg = <0x02014000 0x4000>;
+				interrupts = <66 4>;
+				status = "disabled";
+			};
+
+			ecspi at 02018000 { /* eCSPI5 */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+				reg = <0x02018000 0x4000>;
+				interrupts = <67 4>;
+				status = "disabled";
+			};
+
+			uart0: uart at 02020000 { /* UART1 */
+				compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+				reg = <0x02020000 0x4000>;
+				interrupts = <58 4>;
+				status = "disabled";
+			};
+
+			esai at 02024000 {
+				reg = <0x02024000 0x4000>;
+				interrupts = <83 4>;
+			};
+
+			ssi at 02028000 { /* SSI1 */
+				reg = <0x02028000 0x4000>;
+				interrupts = <78 4>;
+			};
+
+			ssi at 0202c000 { /* SSI2 */
+				reg = <0x0202c000 0x4000>;
+				interrupts = <79 4>;
+			};
+
+			ssi at 02030000 { /* SSI3 */
+				reg = <0x02030000 0x4000>;
+				interrupts = <80 4>;
+			};
+
+			asrc at 02034000 {
+				reg = <0x02034000 0x4000>;
+				interrupts = <82 4>;
+			};
+
+			spba at 0203c000 {
+				reg = <0x0203c000 0x4000>;
+			};
+		};
+
+		vpu at 02040000 {
+			reg = <0x02040000 0x3c000>;
+			interrupts = <35 4 44 4>;
+		};
+
+		aipstz at 0207c000 { /* AIPSTZ1 */
+			reg = <0x0207c000 0x4000>;
+		};
+
+		pwm at 02080000 { /* PWM1 */
+			reg = <0x02080000 0x4000>;
+			interrupts = <115 4>;
+		};
+
+		pwm at 02084000 { /* PWM2 */
+			reg = <0x02084000 0x4000>;
+			interrupts = <116 4>;
+		};
+
+		pwm at 02088000 { /* PWM3 */
+			reg = <0x02088000 0x4000>;
+			interrupts = <117 4>;
+		};
+
+		pwm at 0208c000 { /* PWM4 */
+			reg = <0x0208c000 0x4000>;
+			interrupts = <118 4>;
+		};
+
+		flexcan at 02090000 { /* CAN1 */
+			reg = <0x02090000 0x4000>;
+			interrupts = <142 4>;
+		};
+
+		flexcan at 02094000 { /* CAN2 */
+			reg = <0x02094000 0x4000>;
+			interrupts = <143 4>;
+		};
+
+		gpt at 02098000 {
+			compatible = "fsl,imx6q-gpt";
+			reg = <0x02098000 0x4000>;
+			interrupts = <87 4>;
+		};
+
+		gpio0: gpio at 0209c000 { /* GPIO1 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x0209c000 0x4000>;
+			interrupts = <98 4 99 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio1: gpio at 020a0000 { /* GPIO2 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020a0000 0x4000>;
+			interrupts = <100 4 101 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio2: gpio at 020a4000 { /* GPIO3 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020a4000 0x4000>;
+			interrupts = <102 4 103 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio3: gpio at 020a8000 { /* GPIO4 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020a8000 0x4000>;
+			interrupts = <104 4 105 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio4: gpio at 020ac000 { /* GPIO5 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020ac000 0x4000>;
+			interrupts = <106 4 107 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio5: gpio at 020b0000 { /* GPIO6 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020b0000 0x4000>;
+			interrupts = <108 4 109 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		gpio6: gpio at 020b4000 { /* GPIO7 */
+			compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+			reg = <0x020b4000 0x4000>;
+			interrupts = <110 4 111 4>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		kpp at 020b8000 {
+			reg = <0x020b8000 0x4000>;
+			interrupts = <114 4>;
+		};
+
+		wdog at 020bc000 { /* WDOG1 */
+			compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+			reg = <0x020bc000 0x4000>;
+			interrupts = <112 4>;
+			status = "disabled";
+		};
+
+		wdog at 020c0000 { /* WDOG2 */
+			compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+			reg = <0x020c0000 0x4000>;
+			interrupts = <113 4>;
+			status = "disabled";
+		};
+
+		ccm at 020c4000 {
+			compatible = "fsl,imx6q-ccm";
+			reg = <0x020c4000 0x4000>;
+			interrupts = <119 4 120 4>;
+		};
+
+		anatop at 020c8000 {
+			compatible = "fsl,imx6q-anatop";
+			reg = <0x020c8000 0x1000>;
+			interrupts = <81 4 86 4 159 4>;
+		};
+
+		usbphy at 020c9000 { /* USBPHY1 */
+			reg = <0x020c9000 0x1000>;
+			interrupts = <76 4>;
+		};
+
+		usbphy at 020ca000 { /* USBPHY2 */
+			reg = <0x020ca000 0x1000>;
+			interrupts = <77 4>;
+		};
+
+		snvs at 020cc000 {
+			reg = <0x020cc000 0x4000>;
+			interrupts = <51 4 52 4>;
+		};
+
+		epit at 020d0000 { /* EPIT1 */
+			reg = <0x020d0000 0x4000>;
+			interrupts = <88 4>;
+		};
+
+		epit at 020d4000 { /* EPIT2 */
+			reg = <0x020d4000 0x4000>;
+			interrupts = <89 4>;
+		};
+
+		src at 020d8000 {
+			compatible = "fsl,imx6q-src";
+			reg = <0x020d8000 0x4000>;
+			interrupts = <123 4 128 4>;
+		};
+
+		gpc at 020dc000 {
+			compatible = "fsl,imx6q-gpc";
+			reg = <0x020dc000 0x4000>;
+			interrupts = <121 4 122 4>;
+		};
+
+		iomuxc at 020e0000 {
+			reg = <0x020e0000 0x4000>;
+		};
+
+		dcic at 020e4000 { /* DCIC1 */
+			reg = <0x020e4000 0x4000>;
+			interrupts = <156 4>;
+		};
+
+		dcic at 020e8000 { /* DCIC2 */
+			reg = <0x020e8000 0x4000>;
+			interrupts = <157 4>;
+		};
+
+		sdma at 020ec000 {
+			compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
+			reg = <0x020ec000 0x4000>;
+			interrupts = <34 4>;
+		};
+	};
+
+	aips-bus at 02100000 { /* AIPS2 */
+		compatible = "fsl,aips-bus", "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x02100000 0x100000>;
+		ranges;
+
+		caam at 02100000 {
+			reg = <0x02100000 0x40000>;
+			interrupts = <137 4 138 4>;
+		};
+
+		aipstz at 0217c000 { /* AIPSTZ2 */
+			reg = <0x0217c000 0x4000>;
+		};
+
+		enet at 02188000 {
+			compatible = "fsl,imx6q-fec";
+			reg = <0x02188000 0x4000>;
+			interrupts = <150 4 151 4>;
+			status = "disabled";
+		};
+
+		mlb at 0218c000 {
+			reg = <0x0218c000 0x4000>;
+			interrupts = <85 4 149 4 158 4>;
+		};
+
+		usdhc at 02190000 { /* uSDHC1 */
+			reg = <0x02190000 0x4000>;
+			interrupts = <54 4>;
+		};
+
+		usdhc at 02194000 { /* uSDHC2 */
+			reg = <0x02194000 0x4000>;
+			interrupts = <55 4>;
+		};
+
+		usdhc at 02198000 { /* uSDHC3 */
+			reg = <0x02198000 0x4000>;
+			interrupts = <56 4>;
+		};
+
+		usdhc at 0219c000 { /* uSDHC4 */
+			reg = <0x0219c000 0x4000>;
+			interrupts = <57 4>;
+		};
+
+		i2c at 021a0000 { /* I2C1 */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+			reg = <0x021a0000 0x4000>;
+			interrupts = <68 4>;
+			status = "disabled";
+		};
+
+		i2c at 021a4000 { /* I2C2 */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+			reg = <0x021a4000 0x4000>;
+			interrupts = <69 4>;
+			status = "disabled";
+		};
+
+		i2c at 021a8000 { /* I2C3 */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,imx6q-i2c", "fsl,imx1-i2c";
+			reg = <0x021a8000 0x4000>;
+			interrupts = <70 4>;
+			status = "disabled";
+		};
+
+		romcp at 021ac000 {
+			reg = <0x021ac000 0x4000>;
+		};
+
+		mmdc at 021b0000 { /* MMDC0 */
+			compatible = "fsl,imx6q-mmdc";
+			reg = <0x021b0000 0x4000>;
+		};
+
+		mmdc at 021b4000 { /* MMDC1 */
+			reg = <0x021b4000 0x4000>;
+		};
+
+		weim at 021b8000 {
+			reg = <0x021b8000 0x4000>;
+			interrupts = <46 4>;
+		};
+
+		ocotp at 021bc000 {
+			reg = <0x021bc000 0x4000>;
+		};
+
+		ocotp at 021c0000 {
+			reg = <0x021c0000 0x4000>;
+			interrupts = <53 4>;
+		};
+
+		tzasc at 021d0000 { /* TZASC1 */
+			reg = <0x021d0000 0x4000>;
+			interrupts = <140 4>;
+		};
+
+		tzasc at 021d4000 { /* TZASC2 */
+			reg = <0x021d4000 0x4000>;
+			interrupts = <141 4>;
+		};
+
+		audmux at 021d8000 {
+			reg = <0x021d8000 0x4000>;
+		};
+
+		mipi at 021dc000 { /* MIPI-CSI */
+			reg = <0x021dc000 0x4000>;
+		};
+
+		mipi at 021e0000 { /* MIPI-DSI */
+			reg = <0x021e0000 0x4000>;
+		};
+
+		vdoa at 021e4000 {
+			reg = <0x021e4000 0x4000>;
+			interrupts = <50 4>;
+		};
+
+		uart1: uart at 021e8000 { /* UART2 */
+			compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+			reg = <0x021e8000 0x4000>;
+			interrupts = <59 4>;
+			status = "disabled";
+		};
+
+		uart2: uart at 021ec000 { /* UART3 */
+			compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+			reg = <0x021ec000 0x4000>;
+			interrupts = <60 4>;
+			status = "disabled";
+		};
+
+		uart3: uart at 021f0000 { /* UART4 */
+			compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+			reg = <0x021f0000 0x4000>;
+			interrupts = <61 4>;
+			status = "disabled";
+		};
+
+		uart4: uart at 021f4000 { /* UART5 */
+			compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+			reg = <0x021f4000 0x4000>;
+			interrupts = <62 4>;
+			status = "disabled";
+		};
+	};
+};
-- 
1.7.4.1

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
  2011-09-06  9:58 ` [PATCH 1/6] arm/imx6q: add device tree source Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 18:39   ` Arnd Bergmann
  2011-09-06 20:25   ` Uwe Kleine-König
  2011-09-06  9:58 ` [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src Shawn Guo
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds the core definitions and low-level debug uart support
for imx6q.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/Kconfig                             |    2 +-
 arch/arm/Kconfig.debug                       |    7 +++++
 arch/arm/Makefile                            |    1 +
 arch/arm/mach-imx/Kconfig                    |    4 +++
 arch/arm/mach-imx/Makefile                   |    2 +
 arch/arm/mach-imx/Makefile.boot              |    4 +++
 arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
 arch/arm/plat-mxc/Kconfig                    |    5 ++++
 arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
 arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
 arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
 arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
 arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
 arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
 14 files changed, 115 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-imx/lluart.c
 create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4ea9974..37c20a4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1348,7 +1348,7 @@ config SMP
 	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
 		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
 		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
-		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
+		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
 	select USE_GENERIC_SMP_HELPERS
 	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
 	help
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 965d59a..68fc155 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -155,6 +155,13 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX50 or i.MX53.
 
+	config DEBUG_IMX6Q_UART
+		bool "i.MX6Q Debug UART"
+		depends on SOC_IMX6Q
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on i.MX6Q.
+
 	config DEBUG_S3C_UART0
 		depends on PLAT_SAMSUNG
 		bool "Use S3C UART 0 for low-level debug"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 70c424e..3a0bbe4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
 machine-$(CONFIG_ARCH_MX25)		:= imx
 machine-$(CONFIG_ARCH_MX3)		:= imx
 machine-$(CONFIG_ARCH_MX5)		:= mx5
+machine-$(CONFIG_ARCH_MX6)		:= imx
 machine-$(CONFIG_ARCH_MXS)		:= mxs
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0519dd7..4cf5178 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -58,6 +58,10 @@ config SOC_IMX35
 	select ARCH_MX35
 	select MXC_AVIC
 
+config SOC_IMX6Q
+	bool
+	select ARM_GIC
+	select CPU_V7
 
 if ARCH_MX1
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index e9eb36d..96ecc96 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
 obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
 obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
+
+obj-$(CONFIG_DEBUG_LL) += lluart.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index ebee18b..389a0e3 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
 zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
 params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
 initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
+
+zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
+params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
+initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
new file mode 100644
index 0000000..34205cb
--- /dev/null
+++ b/arch/arm/mach-imx/lluart.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+static struct map_desc imx_lluart_desc = {
+#ifdef CONFIG_DEBUG_IMX6Q_UART
+	.virtual	= MX6Q_UART4_BASE_VADDR,
+	.pfn		= __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
+	.length		= SZ_16K,
+	.type		= MT_DEVICE,
+#endif
+};
+
+void __init imx_lluart_map_io(void)
+{
+	if (imx_lluart_desc.virtual)
+		iotable_init(&imx_lluart_desc, 1);
+}
+
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index a5353fc..e548f9b 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -48,6 +48,11 @@ config ARCH_MX51
 	help
 	  This enables support for systems based on the Freescale i.MX51 family
 
+config ARCH_MX6
+	bool "i.MX6"
+	help
+	  This enables support for systems based on the Freescale i.MX6 family
+
 endchoice
 
 source "arch/arm/mach-imx/Kconfig"
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 07cfdbe..471872a 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -24,9 +24,14 @@
 #define UART_PADDR	MX51_UART1_BASE_ADDR
 #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
 #define UART_PADDR	MX53_UART1_BASE_ADDR
+#elif defined (CONFIG_DEBUG_IMX6Q_UART)
+#define UART_PADDR	MX6Q_UART4_BASE_ADDR
+#define UART_VADDR	MX6Q_UART4_BASE_VADDR
 #endif
 
+#ifndef UART_VADDR
 #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
+#endif
 
 		.macro	addruart, rp, rv
 		ldr	\rp, =UART_PADDR	@ physical
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 066d464..341f800 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -11,6 +11,17 @@
 
 #include <mach/hardware.h>
 
+#ifdef CONFIG_ARM_GIC
+#include <asm/hardware/entry-macro-gic.S>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+#else
+
 #define AVIC_NIMASK	0x04
 
 	@ this macro disables fast irq (not implemented)
@@ -78,3 +89,5 @@
 	movs \irqnr, \irqnr
 #endif
 	.endm
+
+#endif /* CONFIG_ARM_GIC */
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index a8bfd56..e1f84ce 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -97,6 +97,7 @@
 
 #include <mach/mxc.h>
 
+#include <mach/mx6q.h>
 #include <mach/mx50.h>
 #include <mach/mx51.h>
 #include <mach/mx53.h>
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 00e812b..3ae400f 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -14,12 +14,15 @@
 #include <asm-generic/gpio.h>
 
 /*
- * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
+ * SoCs with AVIC interrupt controller have 64 IRQs, those with TZIC
+ * have 128, otherwise those with GIC have 160 IRQs.
  */
-#ifdef CONFIG_MXC_TZIC
+#if defined CONFIG_MXC_AVIC
+#define MXC_INTERNAL_IRQS	64
+#elif defined CONFIG_MXC_TZIC
 #define MXC_INTERNAL_IRQS	128
 #else
-#define MXC_INTERNAL_IRQS	64
+#define MXC_INTERNAL_IRQS	160
 #endif
 
 #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 11be5cd..2b8e186 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -19,6 +19,7 @@
 #define MX50_PHYS_OFFSET	UL(0x70000000)
 #define MX51_PHYS_OFFSET	UL(0x90000000)
 #define MX53_PHYS_OFFSET	UL(0x70000000)
+#define MX6Q_PHYS_OFFSET	UL(0x10000000)
 
 #if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
 # if defined CONFIG_ARCH_MX1
@@ -37,6 +38,8 @@
 #  define PLAT_PHYS_OFFSET		MX51_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MX53
 #  define PLAT_PHYS_OFFSET		MX53_PHYS_OFFSET
+# elif defined CONFIG_SOC_IMX6Q
+#  define PLAT_PHYS_OFFSET		MX6Q_PHYS_OFFSET
 # endif
 #endif
 
diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
new file mode 100644
index 0000000..7432310
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx6q.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+#ifndef __MACH_MX6Q_H__
+#define __MACH_MX6Q_H__
+
+/* static mappings */
+#define IMX6Q_VA(x)		(0xf4000000 + (x))
+
+#define MX6Q_SCU_BASE_ADDR	0x00a00000
+#define MX6Q_CCM_BASE_ADDR	0x020c4000
+#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
+#define MX6Q_UART4_BASE_ADDR	0x021f0000
+
+#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
+#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
+#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
+#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
+
+#endif	/* __MACH_MX6Q_H__ */
-- 
1.7.4.1

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
  2011-09-06  9:58 ` [PATCH 1/6] arm/imx6q: add device tree source Shawn Guo
  2011-09-06  9:58 ` [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 19:14   ` Arnd Bergmann
  2011-09-12  9:46   ` Sascha Hauer
  2011-09-06  9:58 ` [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support Shawn Guo
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds a number of core drivers support for imx6q, including clock,
General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
System Reset Controller (src).

Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Kconfig       |   13 +
 arch/arm/mach-imx/Makefile      |    4 +
 arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/gpc.c         |  110 +++
 arch/arm/mach-imx/mmdc.c        |   71 ++
 arch/arm/mach-imx/src.c         |   52 +
 6 files changed, 2240 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/clock-imx6q.c
 create mode 100644 arch/arm/mach-imx/gpc.c
 create mode 100644 arch/arm/mach-imx/mmdc.c
 create mode 100644 arch/arm/mach-imx/src.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4cf5178..30f2868 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,5 +1,15 @@
 config IMX_HAVE_DMA_V1
 	bool
+
+config HAVE_IMX_GPC
+	bool
+
+config HAVE_IMX_MMDC
+	bool
+
+config HAVE_IMX_SRC
+	bool
+
 #
 # ARCH_MX31 and ARCH_MX35 are left for compatibility
 # Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
@@ -62,6 +72,9 @@ config SOC_IMX6Q
 	bool
 	select ARM_GIC
 	select CPU_V7
+	select HAVE_IMX_GPC
+	select HAVE_IMX_MMDC
+	select HAVE_IMX_SRC
 
 if ARCH_MX1
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 96ecc96..8c21fda 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -63,3 +63,7 @@ obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
 obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
 
 obj-$(CONFIG_DEBUG_LL) += lluart.o
+obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
+obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
+obj-$(CONFIG_HAVE_IMX_SRC) += src.o
+obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
new file mode 100644
index 0000000..7d1bb10
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -0,0 +1,1990 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/div64.h>
+#include <asm/mach/map.h>
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+#define PLL_BASE		IOMEM(MX6Q_ANATOP_BASE_VADDR)
+#define PLL1_SYS		(PLL_BASE + 0x000)
+#define PLL2_BUS		(PLL_BASE + 0x030)
+#define PLL3_USB_OTG		(PLL_BASE + 0x010)
+#define PLL4_AUDIO		(PLL_BASE + 0x070)
+#define PLL5_VIDEO		(PLL_BASE + 0x0a0)
+#define PLL6_MLB		(PLL_BASE + 0x0d0)
+#define PLL7_USB_HOST		(PLL_BASE + 0x020)
+#define PLL8_ENET		(PLL_BASE + 0x0e0)
+#define PFD_480			(PLL_BASE + 0x0f0)
+#define PFD_528			(PLL_BASE + 0x100)
+#define PLL_NUM_OFFSET		0x010
+#define PLL_DENOM_OFFSET	0x020
+
+#define PFD0			7
+#define PFD1			15
+#define PFD2			23
+#define PFD3			31
+#define PFD_FRAC_MASK		0x3f
+
+#define BM_PLL_BYPASS			(0x1 << 16)
+#define BM_PLL_ENABLE			(0x1 << 13)
+#define BM_PLL_POWER_DOWN		(0x1 << 12)
+#define BM_PLL_LOCK			(0x1 << 31)
+#define BP_PLL_SYS_DIV_SELECT		0
+#define BM_PLL_SYS_DIV_SELECT		(0x7f << 0)
+#define BP_PLL_BUS_DIV_SELECT		0
+#define BM_PLL_BUS_DIV_SELECT		(0x1 << 0)
+#define BP_PLL_USB_DIV_SELECT		0
+#define BM_PLL_USB_DIV_SELECT		(0x3 << 0)
+#define BP_PLL_AV_DIV_SELECT		0
+#define BM_PLL_AV_DIV_SELECT		(0x7f << 0)
+#define BP_PLL_ENET_DIV_SELECT		0
+#define BM_PLL_ENET_DIV_SELECT		(0x3 << 0)
+#define BM_PLL_ENET_EN_PCIE		(0x1 << 19)
+#define BM_PLL_ENET_EN_SATA		(0x1 << 20)
+
+#define CCM_BASE	IOMEM(MX6Q_CCM_BASE_VADDR)
+#define CCR		(CCM_BASE + 0x00)
+#define CCDR		(CCM_BASE + 0x04)
+#define CSR		(CCM_BASE + 0x08)
+#define CCSR		(CCM_BASE + 0x0c)
+#define CACRR		(CCM_BASE + 0x10)
+#define CBCDR		(CCM_BASE + 0x14)
+#define CBCMR		(CCM_BASE + 0x18)
+#define CSCMR1		(CCM_BASE + 0x1c)
+#define CSCMR2		(CCM_BASE + 0x20)
+#define CSCDR1		(CCM_BASE + 0x24)
+#define CS1CDR		(CCM_BASE + 0x28)
+#define CS2CDR		(CCM_BASE + 0x2c)
+#define CDCDR		(CCM_BASE + 0x30)
+#define CHSCCDR		(CCM_BASE + 0x34)
+#define CSCDR2		(CCM_BASE + 0x38)
+#define CSCDR3		(CCM_BASE + 0x3c)
+#define CSCDR4		(CCM_BASE + 0x40)
+#define CWDR		(CCM_BASE + 0x44)
+#define CDHIPR		(CCM_BASE + 0x48)
+#define CDCR		(CCM_BASE + 0x4c)
+#define CTOR		(CCM_BASE + 0x50)
+#define CLPCR		(CCM_BASE + 0x54)
+#define CISR		(CCM_BASE + 0x58)
+#define CIMR		(CCM_BASE + 0x5c)
+#define CCOSR		(CCM_BASE + 0x60)
+#define CGPR		(CCM_BASE + 0x64)
+#define CCGR0		(CCM_BASE + 0x68)
+#define CCGR1		(CCM_BASE + 0x6c)
+#define CCGR2		(CCM_BASE + 0x70)
+#define CCGR3		(CCM_BASE + 0x74)
+#define CCGR4		(CCM_BASE + 0x78)
+#define CCGR5		(CCM_BASE + 0x7c)
+#define CCGR6		(CCM_BASE + 0x80)
+#define CCGR7		(CCM_BASE + 0x84)
+#define CMEOR		(CCM_BASE + 0x88)
+
+#define CG0		0
+#define CG1		2
+#define CG2		4
+#define CG3		6
+#define CG4		8
+#define CG5		10
+#define CG6		12
+#define CG7		14
+#define CG8		16
+#define CG9		18
+#define CG10		20
+#define CG11		22
+#define CG12		24
+#define CG13		26
+#define CG14		28
+#define CG15		30
+
+#define BM_CCSR_PLL1_SW_SEL		(0x1 << 2)
+#define BM_CCSR_STEP_SEL		(0x1 << 8)
+
+#define BP_CACRR_ARM_PODF		0
+#define BM_CACRR_ARM_PODF		(0x7 << 0)
+
+#define BP_CBCDR_PERIPH2_CLK2_PODF	0
+#define BM_CBCDR_PERIPH2_CLK2_PODF	(0x7 << 0)
+#define BP_CBCDR_MMDC_CH1_AXI_PODF	3
+#define BM_CBCDR_MMDC_CH1_AXI_PODF	(0x7 << 3)
+#define BP_CBCDR_AXI_SEL		6
+#define BM_CBCDR_AXI_SEL		(0x3 << 6)
+#define BP_CBCDR_IPG_PODF		8
+#define BM_CBCDR_IPG_PODF		(0x3 << 8)
+#define BP_CBCDR_AHB_PODF		10
+#define BM_CBCDR_AHB_PODF		(0x7 << 10)
+#define BP_CBCDR_AXI_PODF		16
+#define BM_CBCDR_AXI_PODF		(0x7 << 16)
+#define BP_CBCDR_MMDC_CH0_AXI_PODF	19
+#define BM_CBCDR_MMDC_CH0_AXI_PODF	(0x7 << 19)
+#define BP_CBCDR_PERIPH_CLK_SEL		25
+#define BM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
+#define BP_CBCDR_PERIPH2_CLK_SEL	26
+#define BM_CBCDR_PERIPH2_CLK_SEL	(0x1 << 26)
+#define BP_CBCDR_PERIPH_CLK2_PODF	27
+#define BM_CBCDR_PERIPH_CLK2_PODF	(0x7 << 27)
+
+#define BP_CBCMR_GPU2D_AXI_SEL		0
+#define BM_CBCMR_GPU2D_AXI_SEL		(0x1 << 0)
+#define BP_CBCMR_GPU3D_AXI_SEL		1
+#define BM_CBCMR_GPU3D_AXI_SEL		(0x1 << 1)
+#define BP_CBCMR_GPU3D_CORE_SEL		4
+#define BM_CBCMR_GPU3D_CORE_SEL		(0x3 << 4)
+#define BP_CBCMR_GPU3D_SHADER_SEL	8
+#define BM_CBCMR_GPU3D_SHADER_SEL	(0x3 << 8)
+#define BP_CBCMR_PCIE_AXI_SEL		10
+#define BM_CBCMR_PCIE_AXI_SEL		(0x1 << 10)
+#define BP_CBCMR_VDO_AXI_SEL		11
+#define BM_CBCMR_VDO_AXI_SEL		(0x1 << 11)
+#define BP_CBCMR_PERIPH_CLK2_SEL	12
+#define BM_CBCMR_PERIPH_CLK2_SEL	(0x3 << 12)
+#define BP_CBCMR_VPU_AXI_SEL		14
+#define BM_CBCMR_VPU_AXI_SEL		(0x3 << 14)
+#define BP_CBCMR_GPU2D_CORE_SEL		16
+#define BM_CBCMR_GPU2D_CORE_SEL		(0x3 << 16)
+#define BP_CBCMR_PRE_PERIPH_CLK_SEL	18
+#define BM_CBCMR_PRE_PERIPH_CLK_SEL	(0x3 << 18)
+#define BP_CBCMR_PERIPH2_CLK2_SEL	20
+#define BM_CBCMR_PERIPH2_CLK2_SEL	(0x1 << 20)
+#define BP_CBCMR_PRE_PERIPH2_CLK_SEL	21
+#define BM_CBCMR_PRE_PERIPH2_CLK_SEL	(0x3 << 21)
+#define BP_CBCMR_GPU2D_CORE_PODF	23
+#define BM_CBCMR_GPU2D_CORE_PODF	(0x7 << 23)
+#define BP_CBCMR_GPU3D_CORE_PODF	26
+#define BM_CBCMR_GPU3D_CORE_PODF	(0x7 << 26)
+#define BP_CBCMR_GPU3D_SHADER_PODF	29
+#define BM_CBCMR_GPU3D_SHADER_PODF	(0x7 << 29)
+
+#define BP_CSCMR1_PERCLK_PODF		0
+#define BM_CSCMR1_PERCLK_PODF		(0x3f << 0)
+#define BP_CSCMR1_SSI1_SEL		10
+#define BM_CSCMR1_SSI1_SEL		(0x3 << 10)
+#define BP_CSCMR1_SSI2_SEL		12
+#define BM_CSCMR1_SSI2_SEL		(0x3 << 12)
+#define BP_CSCMR1_SSI3_SEL		14
+#define BM_CSCMR1_SSI3_SEL		(0x3 << 14)
+#define BP_CSCMR1_USDHC1_SEL		16
+#define BM_CSCMR1_USDHC1_SEL		(0x1 << 16)
+#define BP_CSCMR1_USDHC2_SEL		17
+#define BM_CSCMR1_USDHC2_SEL		(0x1 << 17)
+#define BP_CSCMR1_USDHC3_SEL		18
+#define BM_CSCMR1_USDHC3_SEL		(0x1 << 18)
+#define BP_CSCMR1_USDHC4_SEL		19
+#define BM_CSCMR1_USDHC4_SEL		(0x1 << 19)
+#define BP_CSCMR1_EMI_PODF		20
+#define BM_CSCMR1_EMI_PODF		(0x7 << 20)
+#define BP_CSCMR1_EMI_SLOW_PODF		23
+#define BM_CSCMR1_EMI_SLOW_PODF		(0x7 << 23)
+#define BP_CSCMR1_EMI_SEL		27
+#define BM_CSCMR1_EMI_SEL		(0x3 << 27)
+#define BP_CSCMR1_EMI_SLOW_SEL		29
+#define BM_CSCMR1_EMI_SLOW_SEL		(0x3 << 29)
+
+#define BP_CSCMR2_CAN_PODF		2
+#define BM_CSCMR2_CAN_PODF		(0x3f << 2)
+#define BM_CSCMR2_LDB_DI0_IPU_DIV	(0x1 << 10)
+#define BM_CSCMR2_LDB_DI1_IPU_DIV	(0x1 << 11)
+#define BP_CSCMR2_ESAI_SEL		19
+#define BM_CSCMR2_ESAI_SEL		(0x3 << 19)
+
+#define BP_CSCDR1_UART_PODF		0
+#define BM_CSCDR1_UART_PODF		(0x3f << 0)
+#define BP_CSCDR1_USDHC1_PODF		11
+#define BM_CSCDR1_USDHC1_PODF		(0x7 << 11)
+#define BP_CSCDR1_USDHC2_PODF		16
+#define BM_CSCDR1_USDHC2_PODF		(0x7 << 16)
+#define BP_CSCDR1_USDHC3_PODF		19
+#define BM_CSCDR1_USDHC3_PODF		(0x7 << 19)
+#define BP_CSCDR1_USDHC4_PODF		22
+#define BM_CSCDR1_USDHC4_PODF		(0x7 << 22)
+#define BP_CSCDR1_VPU_AXI_PODF		25
+#define BM_CSCDR1_VPU_AXI_PODF		(0x7 << 25)
+
+#define BP_CS1CDR_SSI1_PODF		0
+#define BM_CS1CDR_SSI1_PODF		(0x3f << 0)
+#define BP_CS1CDR_SSI1_PRED		6
+#define BM_CS1CDR_SSI1_PRED		(0x7 << 6)
+#define BP_CS1CDR_ESAI_PRED		9
+#define BM_CS1CDR_ESAI_PRED		(0x7 << 9)
+#define BP_CS1CDR_SSI3_PODF		16
+#define BM_CS1CDR_SSI3_PODF		(0x3f << 16)
+#define BP_CS1CDR_SSI3_PRED		22
+#define BM_CS1CDR_SSI3_PRED		(0x7 << 22)
+#define BP_CS1CDR_ESAI_PODF		25
+#define BM_CS1CDR_ESAI_PODF		(0x7 << 25)
+
+#define BP_CS2CDR_SSI2_PODF		0
+#define BM_CS2CDR_SSI2_PODF		(0x3f << 0)
+#define BP_CS2CDR_SSI2_PRED		6
+#define BM_CS2CDR_SSI2_PRED		(0x7 << 6)
+#define BP_CS2CDR_LDB_DI0_SEL		9
+#define BM_CS2CDR_LDB_DI0_SEL		(0x7 << 9)
+#define BP_CS2CDR_LDB_DI1_SEL		12
+#define BM_CS2CDR_LDB_DI1_SEL		(0x7 << 12)
+#define BP_CS2CDR_ENFC_SEL		16
+#define BM_CS2CDR_ENFC_SEL		(0x3 << 16)
+#define BP_CS2CDR_ENFC_PRED		18
+#define BM_CS2CDR_ENFC_PRED		(0x7 << 18)
+#define BP_CS2CDR_ENFC_PODF		21
+#define BM_CS2CDR_ENFC_PODF		(0x3f << 21)
+
+#define BP_CDCDR_ASRC_SERIAL_SEL	7
+#define BM_CDCDR_ASRC_SERIAL_SEL	(0x3 << 7)
+#define BP_CDCDR_ASRC_SERIAL_PODF	9
+#define BM_CDCDR_ASRC_SERIAL_PODF	(0x7 << 9)
+#define BP_CDCDR_ASRC_SERIAL_PRED	12
+#define BM_CDCDR_ASRC_SERIAL_PRED	(0x7 << 12)
+#define BP_CDCDR_SPDIF_SEL		20
+#define BM_CDCDR_SPDIF_SEL		(0x3 << 20)
+#define BP_CDCDR_SPDIF_PODF		22
+#define BM_CDCDR_SPDIF_PODF		(0x7 << 22)
+#define BP_CDCDR_SPDIF_PRED		25
+#define BM_CDCDR_SPDIF_PRED		(0x7 << 25)
+#define BP_CDCDR_HSI_TX_PODF		29
+#define BM_CDCDR_HSI_TX_PODF		(0x7 << 29)
+#define BP_CDCDR_HSI_TX_SEL		28
+#define BM_CDCDR_HSI_TX_SEL		(0x1 << 28)
+
+#define BP_CHSCCDR_IPU1_DI0_SEL		0
+#define BM_CHSCCDR_IPU1_DI0_SEL		(0x7 << 0)
+#define BP_CHSCCDR_IPU1_DI0_PRE_PODF	3
+#define BM_CHSCCDR_IPU1_DI0_PRE_PODF	(0x7 << 3)
+#define BP_CHSCCDR_IPU1_DI0_PRE_SEL	6
+#define BM_CHSCCDR_IPU1_DI0_PRE_SEL	(0x7 << 6)
+#define BP_CHSCCDR_IPU1_DI1_SEL		9
+#define BM_CHSCCDR_IPU1_DI1_SEL		(0x7 << 9)
+#define BP_CHSCCDR_IPU1_DI1_PRE_PODF	12
+#define BM_CHSCCDR_IPU1_DI1_PRE_PODF	(0x7 << 12)
+#define BP_CHSCCDR_IPU1_DI1_PRE_SEL	15
+#define BM_CHSCCDR_IPU1_DI1_PRE_SEL	(0x7 << 15)
+
+#define BP_CSCDR2_IPU2_DI0_SEL		0
+#define BM_CSCDR2_IPU2_DI0_SEL		(0x7)
+#define BP_CSCDR2_IPU2_DI0_PRE_PODF	3
+#define BM_CSCDR2_IPU2_DI0_PRE_PODF	(0x7 << 3)
+#define BP_CSCDR2_IPU2_DI0_PRE_SEL	6
+#define BM_CSCDR2_IPU2_DI0_PRE_SEL	(0x7 << 6)
+#define BP_CSCDR2_IPU2_DI1_SEL		9
+#define BM_CSCDR2_IPU2_DI1_SEL		(0x7 << 9)
+#define BP_CSCDR2_IPU2_DI1_PRE_PODF	12
+#define BM_CSCDR2_IPU2_DI1_PRE_PODF	(0x7 << 12)
+#define BP_CSCDR2_IPU2_DI1_PRE_SEL	15
+#define BM_CSCDR2_IPU2_DI1_PRE_SEL	(0x7 << 15)
+#define BP_CSCDR2_ECSPI_CLK_PODF	19
+#define BM_CSCDR2_ECSPI_CLK_PODF	(0x3f << 19)
+
+#define BP_CSCDR3_IPU1_HSP_SEL		9
+#define BM_CSCDR3_IPU1_HSP_SEL		(0x3 << 9)
+#define BP_CSCDR3_IPU1_HSP_PODF		11
+#define BM_CSCDR3_IPU1_HSP_PODF		(0x7 << 11)
+#define BP_CSCDR3_IPU2_HSP_SEL		14
+#define BM_CSCDR3_IPU2_HSP_SEL		(0x3 << 14)
+#define BP_CSCDR3_IPU2_HSP_PODF		16
+#define BM_CSCDR3_IPU2_HSP_PODF		(0x7 << 16)
+
+#define BM_CDHIPR_AXI_PODF_BUSY		(0x1 << 0)
+#define BM_CDHIPR_AHB_PODF_BUSY		(0x1 << 1)
+#define BM_CDHIPR_MMDC_CH1_PODF_BUSY	(0x1 << 2)
+#define BM_CDHIPR_PERIPH2_SEL_BUSY	(0x1 << 3)
+#define BM_CDHIPR_MMDC_CH0_PODF_BUSY	(0x1 << 4)
+#define BM_CDHIPR_PERIPH_SEL_BUSY	(0x1 << 5)
+#define BM_CDHIPR_ARM_PODF_BUSY		(0x1 << 16)
+
+#define BP_CLPCR_LPM			0
+#define BM_CLPCR_LPM			(0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY	(0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define BM_CLPCR_SBYOS			(0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define BM_CLPCR_VSTBY			(0x1 << 8)
+#define BP_CLPCR_STBY_COUNT		9
+#define BM_CLPCR_STBY_COUNT		(0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM		(0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM		(0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS	(0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS	(0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI		(0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI		(0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 27)
+
+#define FREQ_480M	480000000
+#define FREQ_528M	528000000
+#define FREQ_594M	594000000
+#define FREQ_650M	650000000
+#define FREQ_1300M	1300000000
+
+static struct clk pll1_sys;
+static struct clk pll2_bus;
+static struct clk pll3_usb_otg;
+static struct clk pll4_audio;
+static struct clk pll5_video;
+static struct clk pll6_mlb;
+static struct clk pll7_usb_host;
+static struct clk pll8_enet;
+static struct clk apbh_dma_clk;
+static struct clk arm_clk;
+static struct clk ipg_clk;
+static struct clk ahb_clk;
+static struct clk axi_clk;
+static struct clk mmdc_ch0_axi_clk;
+static struct clk mmdc_ch1_axi_clk;
+static struct clk periph_clk;
+static struct clk periph_pre_clk;
+static struct clk periph_clk2_clk;
+static struct clk periph2_clk;
+static struct clk periph2_pre_clk;
+static struct clk periph2_clk2_clk;
+static struct clk gpu2d_core_clk;
+static struct clk gpu3d_core_clk;
+static struct clk gpu3d_shader_clk;
+static struct clk ipg_perclk;
+static struct clk emi_clk;
+static struct clk emi_slow_clk;
+static struct clk can1_clk;
+static struct clk uart_clk;
+static struct clk usdhc1_clk;
+static struct clk usdhc2_clk;
+static struct clk usdhc3_clk;
+static struct clk usdhc4_clk;
+static struct clk vpu_clk;
+static struct clk hsi_tx_clk;
+static struct clk ipu1_di0_pre_clk;
+static struct clk ipu1_di1_pre_clk;
+static struct clk ipu2_di0_pre_clk;
+static struct clk ipu2_di1_pre_clk;
+static struct clk ipu1_clk;
+static struct clk ipu2_clk;
+static struct clk ssi1_clk;
+static struct clk ssi3_clk;
+static struct clk esai_clk;
+static struct clk ssi2_clk;
+static struct clk spdif_clk;
+static struct clk asrc_serial_clk;
+static struct clk gpu2d_axi_clk;
+static struct clk gpu3d_axi_clk;
+static struct clk pcie_clk;
+static struct clk vdo_axi_clk;
+static struct clk ldb_di0_clk;
+static struct clk ldb_di1_clk;
+static struct clk ipu1_di0_clk;
+static struct clk ipu1_di1_clk;
+static struct clk ipu2_di0_clk;
+static struct clk ipu2_di1_clk;
+static struct clk enfc_clk;
+static struct clk dummy_clk = {};
+
+static unsigned long external_high_reference;
+static unsigned long external_low_reference;
+static unsigned long oscillator_reference;
+static unsigned long ckih2_reference;
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+	return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+	return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+	return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+	return ckih2_reference;
+}
+
+static struct clk ckih_clk = {
+	.get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+	.get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+	.get_rate = get_oscillator_reference_clock_rate,
+};
+
+static struct clk ckil_clk = {
+	.get_rate = get_low_reference_clock_rate,
+};
+
+static inline void __iomem *pll_get_reg_addr(struct clk *pll)
+{
+	if (pll == &pll1_sys)
+		return PLL1_SYS;
+	else if (pll == &pll2_bus)
+		return PLL2_BUS;
+	else if (pll == &pll3_usb_otg)
+		return PLL3_USB_OTG;
+	else if (pll == &pll4_audio)
+		return PLL4_AUDIO;
+	else if (pll == &pll5_video)
+		return PLL5_VIDEO;
+	else if (pll == &pll6_mlb)
+		return PLL6_MLB;
+	else if (pll == &pll7_usb_host)
+		return PLL7_USB_HOST;
+	else if (pll == &pll8_enet)
+		return PLL8_ENET;
+	else
+		BUG();
+
+	return NULL;
+}
+
+static int pll_enable(struct clk *clk)
+{
+	int timeout = 0x100000;
+	void __iomem *reg;
+	u32 val;
+
+	reg = pll_get_reg_addr(clk);
+	val = __raw_readl(reg);
+	val &= ~BM_PLL_BYPASS;
+	val &= ~BM_PLL_POWER_DOWN;
+	/* 480MHz PLLs have the opposite definition for power bit */
+	if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
+		val |= BM_PLL_POWER_DOWN;
+	__raw_writel(val, reg);
+
+	/* Wait for PLL to lock */
+	while (!(__raw_readl(reg) & BM_PLL_LOCK) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		return -EBUSY;
+
+	/* Enable the PLL output now */
+	val = __raw_readl(reg);
+	val |= BM_PLL_ENABLE;
+	__raw_writel(val, reg);
+
+	return 0;
+}
+
+static void pll_disable(struct clk *clk)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = pll_get_reg_addr(clk);
+	val = __raw_readl(reg);
+	val &= ~BM_PLL_ENABLE;
+	val |= BM_PLL_BYPASS;
+	val |= BM_PLL_POWER_DOWN;
+	if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
+		val &= ~BM_PLL_POWER_DOWN;
+	__raw_writel(val, reg);
+}
+
+static unsigned long pll1_sys_get_rate(struct clk *clk)
+{
+	u32 div = (__raw_readl(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >>
+		  BP_PLL_SYS_DIV_SELECT;
+
+	return clk_get_rate(clk->parent) * div / 2;
+}
+
+static int pll1_sys_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val, div;
+
+	if (rate < FREQ_650M || rate > FREQ_1300M)
+		return -EINVAL;
+
+	div = rate * 2 / clk_get_rate(clk->parent);
+	val = __raw_readl(PLL1_SYS);
+	val &= ~BM_PLL_SYS_DIV_SELECT;
+	val |= div << BP_PLL_SYS_DIV_SELECT;
+	__raw_writel(val, PLL1_SYS);
+
+	return 0;
+}
+
+static unsigned long pll8_enet_get_rate(struct clk *clk)
+{
+	u32 div = (__raw_readl(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >>
+		  BP_PLL_ENET_DIV_SELECT;
+
+	return 500000000 / (div + 1);
+}
+
+static int pll8_enet_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val, div;
+
+	switch (rate) {
+	case 25000000:
+		div = 0;
+		break;
+	case 50000000:
+		div = 1;
+		break;
+	case 100000000:
+		div = 2;
+		break;
+	case 125000000:
+		div = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val = __raw_readl(PLL8_ENET);
+	val &= ~BM_PLL_ENET_DIV_SELECT;
+	val |= div << BP_PLL_ENET_DIV_SELECT;
+	__raw_writel(val, PLL8_ENET);
+
+	return 0;
+}
+
+static unsigned long pll_av_get_rate(struct clk *clk)
+{
+	void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	u32 mfn = __raw_readl(reg + PLL_NUM_OFFSET);
+	u32 mfd = __raw_readl(reg + PLL_DENOM_OFFSET);
+	u32 div = (__raw_readl(reg) & BM_PLL_AV_DIV_SELECT) >>
+		  BP_PLL_AV_DIV_SELECT;
+
+	return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static int pll_av_set_rate(struct clk *clk, unsigned long rate)
+{
+	void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
+	unsigned int parent_rate = clk_get_rate(clk->parent);
+	u32 val, div;
+	u32 mfn, mfd = 1000000;
+	s64 temp64;
+
+	if (rate < FREQ_650M || rate > FREQ_1300M)
+		return -EINVAL;
+
+	div = rate / parent_rate;
+	temp64 = (u64) (rate - div * parent_rate);
+	temp64 *= mfd;
+	do_div(temp64, parent_rate);
+	mfn = temp64;
+
+	val = __raw_readl(reg);
+	val &= ~BM_PLL_AV_DIV_SELECT;
+	val |= div << BP_PLL_AV_DIV_SELECT;
+	__raw_writel(val, reg);
+	__raw_writel(mfn, reg + PLL_NUM_OFFSET);
+	__raw_writel(mfd, reg + PLL_DENOM_OFFSET);
+
+	return 0;
+}
+
+static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm)
+{
+	void __iomem *reg;
+
+	if (clk == &pll2_bus) {
+		reg = PLL2_BUS;
+		*bp = BP_PLL_BUS_DIV_SELECT;
+		*bm = BM_PLL_BUS_DIV_SELECT;
+	} else if (clk == &pll3_usb_otg) {
+		reg = PLL3_USB_OTG;
+		*bp = BP_PLL_USB_DIV_SELECT;
+		*bm = BM_PLL_USB_DIV_SELECT;
+	} else if (clk == &pll7_usb_host) {
+		reg = PLL7_USB_HOST;
+		*bp = BP_PLL_USB_DIV_SELECT;
+		*bm = BM_PLL_USB_DIV_SELECT;
+	} else {
+		BUG();
+	}
+
+	return reg;
+}
+
+static unsigned long pll_get_rate(struct clk *clk)
+{
+	void __iomem *reg;
+	u32 div, bp, bm;
+
+	reg = pll_get_div_reg_bit(clk, &bp, &bm);
+	div = (__raw_readl(reg) & bm) >> bp;
+
+	return (div == 1) ? clk_get_rate(clk->parent) * 22 :
+			    clk_get_rate(clk->parent) * 20;
+}
+
+static int pll_set_rate(struct clk *clk, unsigned long rate)
+{
+	void __iomem *reg;
+	u32 val, div, bp, bm;
+
+	if (rate == FREQ_528M)
+		div = 1;
+	else if (rate == FREQ_480M)
+		div = 0;
+	else
+		return -EINVAL;
+
+	reg = pll_get_div_reg_bit(clk, &bp, &bm);
+	val = __raw_readl(reg);
+	val &= ~bm;
+	val |= div << bp;
+	__raw_writel(val, reg);
+
+	return 0;
+}
+
+#define pll2_bus_get_rate	pll_get_rate
+#define pll2_bus_set_rate	pll_set_rate
+#define pll3_usb_otg_get_rate	pll_get_rate
+#define pll3_usb_otg_set_rate	pll_set_rate
+#define pll7_usb_host_get_rate	pll_get_rate
+#define pll7_usb_host_set_rate	pll_set_rate
+#define pll4_audio_get_rate	pll_av_get_rate
+#define pll4_audio_set_rate	pll_av_set_rate
+#define pll5_video_get_rate	pll_av_get_rate
+#define pll5_video_set_rate	pll_av_set_rate
+#define pll6_mlb_get_rate	NULL
+#define pll6_mlb_set_rate	NULL
+
+#define DEF_PLL(name)					\
+	static struct clk name = {			\
+		.enable		= pll_enable,		\
+		.disable	= pll_disable,		\
+		.get_rate	= name##_get_rate,	\
+		.set_rate	= name##_set_rate,	\
+		.parent		= &osc_clk,		\
+	}
+
+DEF_PLL(pll1_sys);
+DEF_PLL(pll2_bus);
+DEF_PLL(pll3_usb_otg);
+DEF_PLL(pll4_audio);
+DEF_PLL(pll5_video);
+DEF_PLL(pll6_mlb);
+DEF_PLL(pll7_usb_host);
+DEF_PLL(pll8_enet);
+
+static unsigned long pfd_get_rate(struct clk *clk)
+{
+	u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
+	u32 frac, bp_frac;
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.enable(&apbh_dma_clk);
+
+	bp_frac = clk->enable_shift - 7;
+	frac = __raw_readl(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static int pfd_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val, frac, bp_frac;
+	u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.enable(&apbh_dma_clk);
+
+	/*
+	 * Round up the divider so that we don't set a rate
+	 * higher than what is requested
+	 */
+	tmp += rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	frac = (frac < 12) ? 12 : frac;
+	frac = (frac > 35) ? 35 : frac;
+
+	/*
+	 * The frac field always starts from 7 bits lower
+	 * position of enable bit
+	 */
+	bp_frac = clk->enable_shift - 7;
+	val = __raw_readl(clk->enable_reg);
+	val &= ~(PFD_FRAC_MASK << bp_frac);
+	val |= frac << bp_frac;
+	__raw_writel(val, clk->enable_reg);
+
+	tmp = (u64) clk_get_rate(clk->parent) * 18;
+	do_div(tmp, frac);
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.disable(&apbh_dma_clk);
+
+	return 0;
+}
+
+static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
+{
+	u32 frac;
+	u64 tmp;
+
+	tmp = (u64) clk_get_rate(clk->parent) * 18;
+	tmp += rate / 2;
+	do_div(tmp, rate);
+	frac = tmp;
+	frac = (frac < 12) ? 12 : frac;
+	frac = (frac > 35) ? 35 : frac;
+	tmp = (u64) clk_get_rate(clk->parent) * 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static int pfd_enable(struct clk *clk)
+{
+	u32 val;
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.enable(&apbh_dma_clk);
+
+	val = __raw_readl(clk->enable_reg);
+	val &= ~(1 << clk->enable_shift);
+	__raw_writel(val, clk->enable_reg);
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.disable(&apbh_dma_clk);
+
+	return 0;
+}
+
+static void pfd_disable(struct clk *clk)
+{
+	u32 val;
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.enable(&apbh_dma_clk);
+
+	val = __raw_readl(clk->enable_reg);
+	val |= 1 << clk->enable_shift;
+	__raw_writel(val, clk->enable_reg);
+
+	if (apbh_dma_clk.usecount == 0)
+		apbh_dma_clk.disable(&apbh_dma_clk);
+}
+
+#define DEF_PFD(name, er, es, p)			\
+	static struct clk name = {			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.enable		= pfd_enable,		\
+		.disable	= pfd_disable,		\
+		.get_rate	= pfd_get_rate,		\
+		.set_rate	= pfd_set_rate,		\
+		.round_rate	= pfd_round_rate,	\
+		.parent		= p,			\
+	}
+
+DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus);
+DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus);
+DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus);
+DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg);
+DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
+DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
+DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
+
+static unsigned long pll2_200m_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk pll2_200m = {
+	.parent = &pll2_pfd_400m,
+	.get_rate = pll2_200m_get_rate,
+};
+
+static unsigned long pll3_120m_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 4;
+}
+
+static struct clk pll3_120m = {
+	.parent = &pll3_usb_otg,
+	.get_rate = pll3_120m_get_rate,
+};
+
+static unsigned long pll3_80m_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 6;
+}
+
+static struct clk pll3_80m = {
+	.parent = &pll3_usb_otg,
+	.get_rate = pll3_80m_get_rate,
+};
+
+static unsigned long pll3_60m_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 8;
+}
+
+static struct clk pll3_60m = {
+	.parent = &pll3_usb_otg,
+	.get_rate = pll3_60m_get_rate,
+};
+
+static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 val = __raw_readl(CCSR);
+
+	if (parent == &pll1_sys) {
+		val &= ~BM_CCSR_PLL1_SW_SEL;
+		val &= ~BM_CCSR_STEP_SEL;
+	} else if (parent == &osc_clk) {
+		val |= BM_CCSR_PLL1_SW_SEL;
+		val &= ~BM_CCSR_STEP_SEL;
+	} else if (parent == &pll2_pfd_400m) {
+		val |= BM_CCSR_PLL1_SW_SEL;
+		val |= BM_CCSR_STEP_SEL;
+	} else {
+		return -EINVAL;
+	}
+
+	__raw_writel(val, CCSR);
+
+	return 0;
+}
+
+static struct clk pll1_sw_clk = {
+	.parent = &pll1_sys,
+	.set_parent = pll1_sw_clk_set_parent,
+};
+
+static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf)
+{
+	u32 min_pred, temp_pred, old_err, err;
+
+	if (div >= 512) {
+		*pred = 8;
+		*podf = 64;
+	} else if (div >= 8) {
+		min_pred = (div - 1) / 64 + 1;
+		old_err = 8;
+		for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) {
+			err = div % temp_pred;
+			if (err == 0) {
+				*pred = temp_pred;
+				break;
+			}
+			err = temp_pred - err;
+			if (err < old_err) {
+				old_err = err;
+				*pred = temp_pred;
+			}
+		}
+		*podf = (div + *pred - 1) / *pred;
+	} else if (div < 8) {
+		*pred = div;
+		*podf = 1;
+	}
+}
+
+static int _clk_enable(struct clk *clk)
+{
+	u32 reg;
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 0x3 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+	u32 reg;
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(0x3 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+struct divider {
+	struct clk *clk;
+	void __iomem *reg;
+	u32 bp_pred;
+	u32 bm_pred;
+	u32 bp_podf;
+	u32 bm_podf;
+};
+
+#define DEF_CLK_DIV1(d, c, r, b)				\
+	static struct divider d = {				\
+		.clk = c,					\
+		.reg = r,					\
+		.bp_podf = BP_##r##_##b##_PODF,			\
+		.bm_podf = BM_##r##_##b##_PODF,			\
+	}
+
+DEF_CLK_DIV1(arm_div,		&arm_clk,		CACRR,	ARM);
+DEF_CLK_DIV1(ipg_div,		&ipg_clk,		CBCDR,	IPG);
+DEF_CLK_DIV1(ahb_div,		&ahb_clk,		CBCDR,	AHB);
+DEF_CLK_DIV1(axi_div,		&axi_clk,		CBCDR,	AXI);
+DEF_CLK_DIV1(mmdc_ch0_axi_div,	&mmdc_ch0_axi_clk,	CBCDR,	MMDC_CH0_AXI);
+DEF_CLK_DIV1(mmdc_ch1_axi_div,	&mmdc_ch1_axi_clk,	CBCDR,	MMDC_CH1_AXI);
+DEF_CLK_DIV1(periph_clk2_div,	&periph_clk2_clk,	CBCDR,	PERIPH_CLK2);
+DEF_CLK_DIV1(periph2_clk2_div,	&periph2_clk2_clk,	CBCDR,	PERIPH2_CLK2);
+DEF_CLK_DIV1(gpu2d_core_div,	&gpu2d_core_clk,	CBCMR,	GPU2D_CORE);
+DEF_CLK_DIV1(gpu3d_core_div,	&gpu3d_core_clk,	CBCMR,	GPU3D_CORE);
+DEF_CLK_DIV1(gpu3d_shader_div,	&gpu3d_shader_clk,	CBCMR,	GPU3D_SHADER);
+DEF_CLK_DIV1(ipg_perclk_div,	&ipg_perclk,		CSCMR1,	PERCLK);
+DEF_CLK_DIV1(emi_div,		&emi_clk,		CSCMR1,	EMI);
+DEF_CLK_DIV1(emi_slow_div,	&emi_slow_clk,		CSCMR1,	EMI_SLOW);
+DEF_CLK_DIV1(can_div,		&can1_clk,		CSCMR2,	CAN);
+DEF_CLK_DIV1(uart_div,		&uart_clk,		CSCDR1,	UART);
+DEF_CLK_DIV1(usdhc1_div,	&usdhc1_clk,		CSCDR1,	USDHC1);
+DEF_CLK_DIV1(usdhc2_div,	&usdhc2_clk,		CSCDR1,	USDHC2);
+DEF_CLK_DIV1(usdhc3_div,	&usdhc3_clk,		CSCDR1,	USDHC3);
+DEF_CLK_DIV1(usdhc4_div,	&usdhc4_clk,		CSCDR1,	USDHC4);
+DEF_CLK_DIV1(vpu_div,		&vpu_clk,		CSCDR1,	VPU_AXI);
+DEF_CLK_DIV1(hsi_tx_div,	&hsi_tx_clk,		CDCDR,	HSI_TX);
+DEF_CLK_DIV1(ipu1_di0_pre_div,	&ipu1_di0_pre_clk,	CHSCCDR, IPU1_DI0_PRE);
+DEF_CLK_DIV1(ipu1_di1_pre_div,	&ipu1_di1_pre_clk,	CHSCCDR, IPU1_DI1_PRE);
+DEF_CLK_DIV1(ipu2_di0_pre_div,	&ipu2_di0_pre_clk,	CSCDR2,	IPU2_DI0_PRE);
+DEF_CLK_DIV1(ipu2_di1_pre_div,	&ipu2_di1_pre_clk,	CSCDR2,	IPU2_DI1_PRE);
+DEF_CLK_DIV1(ipu1_div,		&ipu1_clk,		CSCDR3,	IPU1_HSP);
+DEF_CLK_DIV1(ipu2_div,		&ipu2_clk,		CSCDR3,	IPU2_HSP);
+
+#define DEF_CLK_DIV2(d, c, r, b)				\
+	static struct divider d = {				\
+		.clk = c,					\
+		.reg = r,					\
+		.bp_pred = BP_##r##_##b##_PRED,			\
+		.bm_pred = BM_##r##_##b##_PRED,			\
+		.bp_podf = BP_##r##_##b##_PODF,			\
+		.bm_podf = BM_##r##_##b##_PODF,			\
+	}
+
+DEF_CLK_DIV2(ssi1_div,		&ssi1_clk,		CS1CDR,	SSI1);
+DEF_CLK_DIV2(ssi3_div,		&ssi3_clk,		CS1CDR,	SSI3);
+DEF_CLK_DIV2(esai_div,		&esai_clk,		CS1CDR,	ESAI);
+DEF_CLK_DIV2(ssi2_div,		&ssi2_clk,		CS2CDR,	SSI2);
+DEF_CLK_DIV2(enfc_div,		&enfc_clk,		CS2CDR,	ENFC);
+DEF_CLK_DIV2(spdif_div,		&spdif_clk,		CDCDR,	SPDIF);
+DEF_CLK_DIV2(asrc_serial_div,	&asrc_serial_clk,	CDCDR,	ASRC_SERIAL);
+
+static struct divider *dividers[] = {
+	&arm_div,
+	&ipg_div,
+	&ahb_div,
+	&axi_div,
+	&mmdc_ch0_axi_div,
+	&mmdc_ch1_axi_div,
+	&periph_clk2_div,
+	&periph2_clk2_div,
+	&gpu2d_core_div,
+	&gpu3d_core_div,
+	&gpu3d_shader_div,
+	&ipg_perclk_div,
+	&emi_div,
+	&emi_slow_div,
+	&can_div,
+	&uart_div,
+	&usdhc1_div,
+	&usdhc2_div,
+	&usdhc3_div,
+	&usdhc4_div,
+	&vpu_div,
+	&hsi_tx_div,
+	&ipu1_di0_pre_div,
+	&ipu1_di1_pre_div,
+	&ipu2_di0_pre_div,
+	&ipu2_di1_pre_div,
+	&ipu1_div,
+	&ipu2_div,
+	&ssi1_div,
+	&ssi3_div,
+	&esai_div,
+	&ssi2_div,
+	&enfc_div,
+	&spdif_div,
+	&asrc_serial_div,
+};
+
+static unsigned long ldb_di_clk_get_rate(struct clk *clk)
+{
+	u32 val = __raw_readl(CSCMR2);
+
+	val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV :
+				       BM_CSCMR2_LDB_DI1_IPU_DIV;
+	if (val)
+		return clk_get_rate(clk->parent) / 7;
+	else
+		return clk_get_rate(clk->parent) * 2 / 7;
+}
+
+static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	u32 val = __raw_readl(CSCMR2);
+
+	if (rate * 7 <= parent_rate + parent_rate / 20)
+		val |= BM_CSCMR2_LDB_DI0_IPU_DIV;
+	else
+		val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV;
+
+	__raw_writel(val, CSCMR2);
+
+	return 0;
+}
+
+static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+
+	if (rate * 7 <= parent_rate + parent_rate / 20)
+		return parent_rate / 7;
+	else
+		return 2 * parent_rate / 7;
+}
+
+static unsigned long _clk_get_rate(struct clk *clk)
+{
+	struct divider *d;
+	u32 val, pred, podf;
+	int i, num;
+
+	if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
+		return ldb_di_clk_get_rate(clk);
+
+	num = ARRAY_SIZE(dividers);
+	for (i = 0; i < num; i++)
+		if (dividers[i]->clk == clk) {
+			d = dividers[i];
+			break;
+		}
+	if (i == num)
+		return clk_get_rate(clk->parent);
+
+	val = __raw_readl(d->reg);
+	pred = ((val & d->bm_pred) >> d->bp_pred) + 1;
+	podf = ((val & d->bm_podf) >> d->bp_podf) + 1;
+
+	return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int clk_busy_wait(struct clk *clk)
+{
+	int timeout = 0x100000;
+	u32 bm;
+
+	if (clk == &axi_clk)
+		bm = BM_CDHIPR_AXI_PODF_BUSY;
+	else if (clk == &ahb_clk)
+		bm = BM_CDHIPR_AHB_PODF_BUSY;
+	else if (clk == &mmdc_ch0_axi_clk)
+		bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY;
+	else if (clk == &periph_clk)
+		bm = BM_CDHIPR_PERIPH_SEL_BUSY;
+	else if (clk == &arm_clk)
+		bm = BM_CDHIPR_ARM_PODF_BUSY;
+	else
+		return -EINVAL;
+
+	while ((__raw_readl(CDHIPR) & bm) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout))
+		return -EBUSY;
+
+	return 0;
+}
+
+static int _clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	struct divider *d;
+	u32 val, div, max_div, pred = 0, podf;
+	int i, num;
+
+	if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
+		return ldb_di_clk_set_rate(clk, rate);
+
+	num = ARRAY_SIZE(dividers);
+	for (i = 0; i < num; i++)
+		if (dividers[i]->clk == clk) {
+			d = dividers[i];
+			break;
+		}
+	if (i == num)
+		return -EINVAL;
+
+	max_div = ((d->bm_pred >> d->bp_pred) + 1) *
+		  ((d->bm_pred >> d->bp_pred) + 1);
+
+	div = parent_rate / rate;
+	if (div == 0)
+		div++;
+
+	if ((parent_rate / div != rate) || div > max_div)
+		return -EINVAL;
+
+	if (d->bm_pred) {
+		calc_pred_podf_dividers(div, &pred, &podf);
+	} else {
+		pred = 1;
+		podf = div;
+	}
+
+	val = __raw_readl(d->reg);
+	val &= ~(d->bm_pred | d->bm_podf);
+	val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf;
+	__raw_writel(val, d->reg);
+
+	if (clk == &axi_clk || clk == &ahb_clk ||
+	    clk == &mmdc_ch0_axi_clk || clk == &arm_clk)
+		return clk_busy_wait(clk);
+
+	return 0;
+}
+
+static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	u32 div = parent_rate / rate;
+	u32 div_max, pred = 0, podf;
+	struct divider *d;
+	int i, num;
+
+	if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
+		return ldb_di_clk_round_rate(clk, rate);
+
+	num = ARRAY_SIZE(dividers);
+	for (i = 0; i < num; i++)
+		if (dividers[i]->clk == clk) {
+			d = dividers[i];
+			break;
+		}
+	if (i == num)
+		return -EINVAL;
+
+	if (div == 0 || parent_rate % rate)
+		div++;
+
+	if (d->bm_pred) {
+		calc_pred_podf_dividers(div, &pred, &podf);
+		div = pred * podf;
+	} else {
+		div_max = (d->bm_podf >> d->bp_podf) + 1;
+		if (div > div_max)
+			div = div_max;
+	}
+
+	return parent_rate / div;
+}
+
+struct multiplexer {
+	struct clk *clk;
+	void __iomem *reg;
+	u32 bp;
+	u32 bm;
+	int pnum;
+	struct clk *parents[];
+};
+
+static struct multiplexer axi_mux = {
+	.clk = &axi_clk,
+	.reg = CBCDR,
+	.bp = BP_CBCDR_AXI_SEL,
+	.bm = BM_CBCDR_AXI_SEL,
+	.parents = {
+		&periph_clk,
+		&pll2_pfd_400m,
+		&pll3_pfd_540m,
+		NULL
+	},
+};
+
+static struct multiplexer periph_mux = {
+	.clk = &periph_clk,
+	.reg = CBCDR,
+	.bp = BP_CBCDR_PERIPH_CLK_SEL,
+	.bm = BM_CBCDR_PERIPH_CLK_SEL,
+	.parents = {
+		&periph_pre_clk,
+		&periph_clk2_clk,
+		NULL
+	},
+};
+
+static struct multiplexer periph_pre_mux = {
+	.clk = &periph_pre_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_PRE_PERIPH_CLK_SEL,
+	.bm = BM_CBCMR_PRE_PERIPH_CLK_SEL,
+	.parents = {
+		&pll2_bus,
+		&pll2_pfd_400m,
+		&pll2_pfd_352m,
+		&pll2_200m,
+		NULL
+	},
+};
+
+static struct multiplexer periph_clk2_mux = {
+	.clk = &periph_clk2_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_PERIPH_CLK2_SEL,
+	.bm = BM_CBCMR_PERIPH_CLK2_SEL,
+	.parents = {
+		&pll3_usb_otg,
+		&osc_clk,
+		NULL
+	},
+};
+
+static struct multiplexer periph2_mux = {
+	.clk = &periph2_clk,
+	.reg = CBCDR,
+	.bp = BP_CBCDR_PERIPH2_CLK_SEL,
+	.bm = BM_CBCDR_PERIPH2_CLK_SEL,
+	.parents = {
+		&periph2_pre_clk,
+		&periph2_clk2_clk,
+		NULL
+	},
+};
+
+static struct multiplexer periph2_pre_mux = {
+	.clk = &periph2_pre_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL,
+	.bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL,
+	.parents = {
+		&pll2_bus,
+		&pll2_pfd_400m,
+		&pll2_pfd_352m,
+		&pll2_200m,
+		NULL
+	},
+};
+
+static struct multiplexer periph2_clk2_mux = {
+	.clk = &periph2_clk2_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_PERIPH2_CLK2_SEL,
+	.bm = BM_CBCMR_PERIPH2_CLK2_SEL,
+	.parents = {
+		&pll3_usb_otg,
+		&osc_clk,
+		NULL
+	},
+};
+
+static struct multiplexer gpu2d_axi_mux = {
+	.clk = &gpu2d_axi_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_GPU2D_AXI_SEL,
+	.bm = BM_CBCMR_GPU2D_AXI_SEL,
+	.parents = {
+		&axi_clk,
+		&ahb_clk,
+		NULL
+	},
+};
+
+static struct multiplexer gpu3d_axi_mux = {
+	.clk = &gpu3d_axi_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_GPU3D_AXI_SEL,
+	.bm = BM_CBCMR_GPU3D_AXI_SEL,
+	.parents = {
+		&axi_clk,
+		&ahb_clk,
+		NULL
+	},
+};
+
+static struct multiplexer gpu3d_core_mux = {
+	.clk = &gpu3d_core_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_GPU3D_CORE_SEL,
+	.bm = BM_CBCMR_GPU3D_CORE_SEL,
+	.parents = {
+		&mmdc_ch0_axi_clk,
+		&pll3_usb_otg,
+		&pll2_pfd_594m,
+		&pll2_pfd_400m,
+		NULL
+	},
+};
+
+static struct multiplexer gpu3d_shader_mux = {
+	.clk = &gpu3d_shader_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_GPU3D_SHADER_SEL,
+	.bm = BM_CBCMR_GPU3D_SHADER_SEL,
+	.parents = {
+		&mmdc_ch0_axi_clk,
+		&pll3_usb_otg,
+		&pll2_pfd_594m,
+		&pll3_pfd_720m,
+		NULL
+	},
+};
+
+static struct multiplexer pcie_axi_mux = {
+	.clk = &pcie_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_PCIE_AXI_SEL,
+	.bm = BM_CBCMR_PCIE_AXI_SEL,
+	.parents = {
+		&axi_clk,
+		&ahb_clk,
+		NULL
+	},
+};
+
+static struct multiplexer vdo_axi_mux = {
+	.clk = &vdo_axi_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_VDO_AXI_SEL,
+	.bm = BM_CBCMR_VDO_AXI_SEL,
+	.parents = {
+		&axi_clk,
+		&ahb_clk,
+		NULL
+	},
+};
+
+static struct multiplexer vpu_axi_mux = {
+	.clk = &vpu_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_VPU_AXI_SEL,
+	.bm = BM_CBCMR_VPU_AXI_SEL,
+	.parents = {
+		&axi_clk,
+		&pll2_pfd_400m,
+		&pll2_pfd_352m,
+		NULL
+	},
+};
+
+static struct multiplexer gpu2d_core_mux = {
+	.clk = &gpu2d_core_clk,
+	.reg = CBCMR,
+	.bp = BP_CBCMR_GPU2D_CORE_SEL,
+	.bm = BM_CBCMR_GPU2D_CORE_SEL,
+	.parents = {
+		&axi_clk,
+		&pll3_usb_otg,
+		&pll2_pfd_352m,
+		&pll2_pfd_400m,
+		NULL
+	},
+};
+
+#define DEF_SSI_MUX(id)							\
+	static struct multiplexer ssi##id##_mux = {			\
+		.clk = &ssi##id##_clk,					\
+		.reg = CSCMR1,						\
+		.bp = BP_CSCMR1_SSI##id##_SEL,				\
+		.bm = BM_CSCMR1_SSI##id##_SEL,				\
+		.parents = {						\
+			&pll3_pfd_508m,					\
+			&pll3_pfd_454m,					\
+			&pll4_audio,					\
+			NULL						\
+		},							\
+	}
+
+DEF_SSI_MUX(1);
+DEF_SSI_MUX(2);
+DEF_SSI_MUX(3);
+
+#define DEF_USDHC_MUX(id)						\
+	static struct multiplexer usdhc##id##_mux = {			\
+		.clk = &usdhc##id##_clk,				\
+		.reg = CSCMR1,						\
+		.bp = BP_CSCMR1_USDHC##id##_SEL,			\
+		.bm = BM_CSCMR1_USDHC##id##_SEL,			\
+		.parents = {						\
+			&pll2_pfd_400m,					\
+			&pll2_pfd_352m,					\
+			NULL						\
+		},							\
+	}
+
+DEF_USDHC_MUX(1);
+DEF_USDHC_MUX(2);
+DEF_USDHC_MUX(3);
+DEF_USDHC_MUX(4);
+
+static struct multiplexer emi_mux = {
+	.clk = &emi_clk,
+	.reg = CSCMR1,
+	.bp = BP_CSCMR1_EMI_SEL,
+	.bm = BM_CSCMR1_EMI_SEL,
+	.parents = {
+		&axi_clk,
+		&pll3_usb_otg,
+		&pll2_pfd_400m,
+		&pll2_pfd_352m,
+		NULL
+	},
+};
+
+static struct multiplexer emi_slow_mux = {
+	.clk = &emi_slow_clk,
+	.reg = CSCMR1,
+	.bp = BP_CSCMR1_EMI_SLOW_SEL,
+	.bm = BM_CSCMR1_EMI_SLOW_SEL,
+	.parents = {
+		&axi_clk,
+		&pll3_usb_otg,
+		&pll2_pfd_400m,
+		&pll2_pfd_352m,
+		NULL
+	},
+};
+
+static struct multiplexer esai_mux = {
+	.clk = &esai_clk,
+	.reg = CSCMR2,
+	.bp = BP_CSCMR2_ESAI_SEL,
+	.bm = BM_CSCMR2_ESAI_SEL,
+	.parents = {
+		&pll4_audio,
+		&pll3_pfd_508m,
+		&pll3_pfd_454m,
+		&pll3_usb_otg,
+		NULL
+	},
+};
+
+#define DEF_LDB_DI_MUX(id)						\
+	static struct multiplexer ldb_di##id##_mux = {			\
+		.clk = &ldb_di##id##_clk,				\
+		.reg = CS2CDR,						\
+		.bp = BP_CS2CDR_LDB_DI##id##_SEL,			\
+		.bm = BM_CS2CDR_LDB_DI##id##_SEL,			\
+		.parents = {						\
+			&pll5_video,					\
+			&pll2_pfd_352m,					\
+			&pll2_pfd_400m,					\
+			&pll3_pfd_540m,					\
+			&pll3_usb_otg,					\
+			NULL						\
+		},							\
+	}
+
+DEF_LDB_DI_MUX(0);
+DEF_LDB_DI_MUX(1);
+
+static struct multiplexer enfc_mux = {
+	.clk = &enfc_clk,
+	.reg = CS2CDR,
+	.bp = BP_CS2CDR_ENFC_SEL,
+	.bm = BM_CS2CDR_ENFC_SEL,
+	.parents = {
+		&pll2_pfd_352m,
+		&pll2_bus,
+		&pll3_usb_otg,
+		&pll2_pfd_400m,
+		NULL
+	},
+};
+
+static struct multiplexer spdif_mux = {
+	.clk = &spdif_clk,
+	.reg = CDCDR,
+	.bp = BP_CDCDR_SPDIF_SEL,
+	.bm = BM_CDCDR_SPDIF_SEL,
+	.parents = {
+		&pll4_audio,
+		&pll3_pfd_508m,
+		&pll3_pfd_454m,
+		&pll3_usb_otg,
+		NULL
+	},
+};
+
+static struct multiplexer asrc_serial_mux = {
+	.clk = &asrc_serial_clk,
+	.reg = CDCDR,
+	.bp = BP_CDCDR_ASRC_SERIAL_SEL,
+	.bm = BM_CDCDR_ASRC_SERIAL_SEL,
+	.parents = {
+		&pll4_audio,
+		&pll3_pfd_508m,
+		&pll3_pfd_454m,
+		&pll3_usb_otg,
+		NULL
+	},
+};
+
+static struct multiplexer hsi_tx_mux = {
+	.clk = &hsi_tx_clk,
+	.reg = CDCDR,
+	.bp = BP_CDCDR_HSI_TX_SEL,
+	.bm = BM_CDCDR_HSI_TX_SEL,
+	.parents = {
+		&pll3_120m,
+		&pll2_pfd_400m,
+		NULL
+	},
+};
+
+#define DEF_IPU_DI_PRE_MUX(r, i, d)					\
+	static struct multiplexer ipu##i##_di##d##_pre_mux = {		\
+		.clk = &ipu##i##_di##d##_pre_clk,			\
+		.reg = r,						\
+		.bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL,		\
+		.bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL,		\
+		.parents = {						\
+			&mmdc_ch0_axi_clk,				\
+			&pll3_usb_otg,					\
+			&pll5_video,					\
+			&pll2_pfd_352m,					\
+			&pll2_pfd_400m,					\
+			&pll3_pfd_540m,					\
+			NULL						\
+		},							\
+	}
+
+DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0);
+DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1);
+DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0);
+DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1);
+
+#define DEF_IPU_DI_MUX(r, i, d)						\
+	static struct multiplexer ipu##i##_di##d##_mux = {		\
+		.clk = &ipu##i##_di##d##_clk,				\
+		.reg = r,						\
+		.bp = BP_##r##_IPU##i##_DI##d##_SEL,			\
+		.bm = BM_##r##_IPU##i##_DI##d##_SEL,			\
+		.parents = {						\
+			&ipu##i##_di##d##_pre_clk,			\
+			&dummy_clk,					\
+			&dummy_clk,					\
+			&ldb_di0_clk,					\
+			&ldb_di1_clk,					\
+			NULL						\
+		},							\
+	}
+
+DEF_IPU_DI_MUX(CHSCCDR, 1, 0);
+DEF_IPU_DI_MUX(CHSCCDR, 1, 1);
+DEF_IPU_DI_MUX(CSCDR2, 2, 0);
+DEF_IPU_DI_MUX(CSCDR2, 2, 1);
+
+#define DEF_IPU_MUX(id)							\
+	static struct multiplexer ipu##id##_mux = {			\
+		.clk = &ipu##id##_clk,					\
+		.reg = CSCDR3,						\
+		.bp = BP_CSCDR3_IPU##id##_HSP_SEL,			\
+		.bm = BM_CSCDR3_IPU##id##_HSP_SEL,			\
+		.parents = {						\
+			&mmdc_ch0_axi_clk,				\
+			&pll2_pfd_400m,					\
+			&pll3_120m,					\
+			&pll3_pfd_540m,					\
+			NULL						\
+		},							\
+	}
+
+DEF_IPU_MUX(1);
+DEF_IPU_MUX(2);
+
+static struct multiplexer *multiplexers[] = {
+	&axi_mux,
+	&periph_mux,
+	&periph_pre_mux,
+	&periph_clk2_mux,
+	&periph2_mux,
+	&periph2_pre_mux,
+	&periph2_clk2_mux,
+	&gpu2d_axi_mux,
+	&gpu3d_axi_mux,
+	&gpu3d_core_mux,
+	&gpu3d_shader_mux,
+	&pcie_axi_mux,
+	&vdo_axi_mux,
+	&vpu_axi_mux,
+	&gpu2d_core_mux,
+	&ssi1_mux,
+	&ssi2_mux,
+	&ssi3_mux,
+	&usdhc1_mux,
+	&usdhc2_mux,
+	&usdhc3_mux,
+	&usdhc4_mux,
+	&emi_mux,
+	&emi_slow_mux,
+	&esai_mux,
+	&ldb_di0_mux,
+	&ldb_di1_mux,
+	&enfc_mux,
+	&spdif_mux,
+	&asrc_serial_mux,
+	&hsi_tx_mux,
+	&ipu1_di0_pre_mux,
+	&ipu1_di0_mux,
+	&ipu1_di1_pre_mux,
+	&ipu1_di1_mux,
+	&ipu2_di0_pre_mux,
+	&ipu2_di0_mux,
+	&ipu2_di1_pre_mux,
+	&ipu2_di1_mux,
+	&ipu1_mux,
+	&ipu2_mux,
+};
+
+static int _clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct multiplexer *m;
+	int i, num;
+	u32 val;
+
+	num = ARRAY_SIZE(multiplexers);
+	for (i = 0; i < num; i++)
+		if (multiplexers[i]->clk == clk) {
+			m = multiplexers[i];
+			break;
+		}
+	if (i == num)
+		return -EINVAL;
+
+	i = 0;
+	while (m->parents[i]) {
+		if (parent == m->parents[i])
+			break;
+		i++;
+	}
+	if (!m->parents[i])
+		return -EINVAL;
+
+	val = __raw_readl(m->reg);
+	val &= ~m->bm;
+	val |= i << m->bp;
+	__raw_writel(val, m->reg);
+
+	if (clk == &periph_clk)
+		return clk_busy_wait(clk);
+
+	return 0;
+}
+
+#define DEF_NG_CLK(name, p)				\
+	static struct clk name = {			\
+		.get_rate	= _clk_get_rate,	\
+		.set_rate	= _clk_set_rate,	\
+		.round_rate	= _clk_round_rate,	\
+		.set_parent	= _clk_set_parent,	\
+		.parent		= p,			\
+	}
+
+DEF_NG_CLK(periph_clk2_clk,	&osc_clk);
+DEF_NG_CLK(periph_pre_clk,	&pll2_bus);
+DEF_NG_CLK(periph_clk,		&periph_pre_clk);
+DEF_NG_CLK(periph2_clk2_clk,	&osc_clk);
+DEF_NG_CLK(periph2_pre_clk,	&pll2_bus);
+DEF_NG_CLK(periph2_clk,		&periph2_pre_clk);
+DEF_NG_CLK(axi_clk,		&periph_clk);
+DEF_NG_CLK(emi_clk,		&axi_clk);
+DEF_NG_CLK(arm_clk,		&pll1_sw_clk);
+DEF_NG_CLK(ahb_clk,		&periph_clk);
+DEF_NG_CLK(ipg_clk,		&ahb_clk);
+DEF_NG_CLK(ipg_perclk,		&ipg_clk);
+DEF_NG_CLK(ipu1_di0_pre_clk,	&pll3_pfd_540m);
+DEF_NG_CLK(ipu1_di1_pre_clk,	&pll3_pfd_540m);
+DEF_NG_CLK(ipu2_di0_pre_clk,	&pll3_pfd_540m);
+DEF_NG_CLK(ipu2_di1_pre_clk,	&pll3_pfd_540m);
+DEF_NG_CLK(asrc_serial_clk,	&pll3_usb_otg);
+
+#define DEF_CLK(name, er, es, p, s)			\
+	static struct clk name = {			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.enable		= _clk_enable,		\
+		.disable	= _clk_disable,		\
+		.get_rate	= _clk_get_rate,	\
+		.set_rate	= _clk_set_rate,	\
+		.round_rate	= _clk_round_rate,	\
+		.set_parent	= _clk_set_parent,	\
+		.parent		= p,			\
+		.secondary	= s,			\
+	}
+
+DEF_CLK(aips_tz1_clk,	  CCGR0, CG0,  &ahb_clk,	  NULL);
+DEF_CLK(aips_tz2_clk,	  CCGR0, CG1,  &ahb_clk,	  NULL);
+DEF_CLK(apbh_dma_clk,	  CCGR0, CG2,  &ahb_clk,	  NULL);
+DEF_CLK(asrc_clk,	  CCGR0, CG3,  &pll4_audio,	  NULL);
+DEF_CLK(can1_serial_clk,  CCGR0, CG8,  &pll3_usb_otg,	  NULL);
+DEF_CLK(can1_clk,	  CCGR0, CG7,  &pll3_usb_otg,	  &can1_serial_clk);
+DEF_CLK(can2_serial_clk,  CCGR0, CG10, &pll3_usb_otg,	  NULL);
+DEF_CLK(can2_clk,	  CCGR0, CG9,  &pll3_usb_otg,	  &can2_serial_clk);
+DEF_CLK(ecspi1_clk,	  CCGR1, CG0,  &pll3_60m,	  NULL);
+DEF_CLK(ecspi2_clk,	  CCGR1, CG1,  &pll3_60m,	  NULL);
+DEF_CLK(ecspi3_clk,	  CCGR1, CG2,  &pll3_60m,	  NULL);
+DEF_CLK(ecspi4_clk,	  CCGR1, CG3,  &pll3_60m,	  NULL);
+DEF_CLK(ecspi5_clk,	  CCGR1, CG4,  &pll3_60m,	  NULL);
+DEF_CLK(enet_clk,	  CCGR1, CG5,  &pll8_enet,	  NULL);
+DEF_CLK(esai_clk,	  CCGR1, CG8,  &pll3_usb_otg,	  NULL);
+DEF_CLK(gpt_serial_clk,	  CCGR1, CG11, &ipg_perclk,	  NULL);
+DEF_CLK(gpt_clk,	  CCGR1, CG10, &ipg_perclk,	  &gpt_serial_clk);
+DEF_CLK(gpu2d_core_clk,	  CCGR1, CG12, &pll2_pfd_352m,	  &gpu2d_axi_clk);
+DEF_CLK(gpu3d_core_clk,	  CCGR1, CG13, &pll2_pfd_594m,	  &gpu3d_axi_clk);
+DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m,	  &gpu3d_axi_clk);
+DEF_CLK(hdmi_iahb_clk,	  CCGR2, CG0,  &ahb_clk,	  NULL);
+DEF_CLK(hdmi_isfr_clk,	  CCGR2, CG2,  &pll3_pfd_540m,	  &hdmi_iahb_clk);
+DEF_CLK(i2c1_clk,	  CCGR2, CG3,  &ipg_perclk,	  NULL);
+DEF_CLK(i2c2_clk,	  CCGR2, CG4,  &ipg_perclk,	  NULL);
+DEF_CLK(i2c3_clk,	  CCGR2, CG5,  &ipg_perclk,	  NULL);
+DEF_CLK(iim_clk,	  CCGR2, CG6,  &ipg_clk,	  NULL);
+DEF_CLK(enfc_clk,	  CCGR2, CG7,  &pll2_pfd_352m,	  NULL);
+DEF_CLK(ipu1_clk,	  CCGR3, CG0,  &mmdc_ch0_axi_clk, NULL);
+DEF_CLK(ipu1_di0_clk,	  CCGR3, CG1,  &ipu1_di0_pre_clk, NULL);
+DEF_CLK(ipu1_di1_clk,	  CCGR3, CG2,  &ipu1_di1_pre_clk, NULL);
+DEF_CLK(ipu2_clk,	  CCGR3, CG3,  &mmdc_ch0_axi_clk, NULL);
+DEF_CLK(ipu2_di0_clk,	  CCGR3, CG4,  &ipu2_di0_pre_clk, NULL);
+DEF_CLK(ipu2_di1_clk,	  CCGR3, CG5,  &ipu2_di1_pre_clk, NULL);
+DEF_CLK(ldb_di0_clk,	  CCGR3, CG6,  &pll3_pfd_540m,	  NULL);
+DEF_CLK(ldb_di1_clk,	  CCGR3, CG7,  &pll3_pfd_540m,	  NULL);
+DEF_CLK(hsi_tx_clk,	  CCGR3, CG8,  &pll2_pfd_400m,	  NULL);
+DEF_CLK(mlb_clk,	  CCGR3, CG9,  &pll6_mlb,	  NULL);
+DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk,	  NULL);
+DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk,	  &mmdc_ch0_ipg_clk);
+DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk,	  NULL);
+DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk,	  &mmdc_ch1_ipg_clk);
+DEF_CLK(openvg_axi_clk,   CCGR3, CG13, &axi_clk,	  NULL);
+DEF_CLK(pwm1_clk,	  CCGR4, CG8,  &ipg_perclk,	  NULL);
+DEF_CLK(pwm2_clk,	  CCGR4, CG9,  &ipg_perclk,	  NULL);
+DEF_CLK(pwm3_clk,	  CCGR4, CG10, &ipg_perclk,	  NULL);
+DEF_CLK(pwm4_clk,	  CCGR4, CG11, &ipg_perclk,	  NULL);
+DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk,	  NULL);
+DEF_CLK(gpmi_bch_clk,	  CCGR4, CG13, &usdhc4_clk,	  &gpmi_bch_apb_clk);
+DEF_CLK(gpmi_apb_clk,	  CCGR4, CG15, &usdhc3_clk,	  &gpmi_bch_clk);
+DEF_CLK(gpmi_io_clk,	  CCGR4, CG14, &enfc_clk,	  &gpmi_apb_clk);
+DEF_CLK(sdma_clk,	  CCGR5, CG3,  &ahb_clk,	  NULL);
+DEF_CLK(spba_clk,	  CCGR5, CG6,  &ipg_clk,	  NULL);
+DEF_CLK(spdif_clk,	  CCGR5, CG7,  &pll3_usb_otg,	  &spba_clk);
+DEF_CLK(ssi1_clk,	  CCGR5, CG9,  &pll3_pfd_508m,	  NULL);
+DEF_CLK(ssi2_clk,	  CCGR5, CG10, &pll3_pfd_508m,	  NULL);
+DEF_CLK(ssi3_clk,	  CCGR5, CG11, &pll3_pfd_508m,	  NULL);
+DEF_CLK(uart_serial_clk,  CCGR5, CG13, &pll3_usb_otg,	  NULL);
+DEF_CLK(uart_clk,	  CCGR5, CG12, &pll3_80m,	  &uart_serial_clk);
+DEF_CLK(usboh3_clk,	  CCGR6, CG0,  &ipg_clk,	  NULL);
+DEF_CLK(usdhc1_clk,	  CCGR6, CG1,  &pll2_pfd_400m,	  NULL);
+DEF_CLK(usdhc2_clk,	  CCGR6, CG2,  &pll2_pfd_400m,	  NULL);
+DEF_CLK(usdhc3_clk,	  CCGR6, CG3,  &pll2_pfd_400m,	  NULL);
+DEF_CLK(usdhc4_clk,	  CCGR6, CG4,  &pll2_pfd_400m,	  NULL);
+DEF_CLK(emi_slow_clk,	  CCGR6, CG5,  &axi_clk,	  NULL);
+DEF_CLK(vdo_axi_clk,	  CCGR6, CG6,  &axi_clk,	  NULL);
+DEF_CLK(vpu_clk,	  CCGR6, CG7,  &axi_clk,	  NULL);
+
+static int pcie_clk_enable(struct clk *clk)
+{
+	u32 val;
+
+	val = __raw_readl(PLL8_ENET);
+	val |= BM_PLL_ENET_EN_PCIE;
+	__raw_writel(val, PLL8_ENET);
+
+	return _clk_enable(clk);
+}
+
+static void pcie_clk_disable(struct clk *clk)
+{
+	u32 val;
+
+	_clk_disable(clk);
+
+	val = __raw_readl(PLL8_ENET);
+	val &= BM_PLL_ENET_EN_PCIE;
+	__raw_writel(val, PLL8_ENET);
+}
+
+static struct clk pcie_clk = {
+	.enable_reg = CCGR4,
+	.enable_shift = CG0,
+	.enable = pcie_clk_enable,
+	.disable = pcie_clk_disable,
+	.set_parent = _clk_set_parent,
+	.parent = &axi_clk,
+	.secondary = &pll8_enet,
+};
+
+static int sata_clk_enable(struct clk *clk)
+{
+	u32 val;
+
+	val = __raw_readl(PLL8_ENET);
+	val |= BM_PLL_ENET_EN_SATA;
+	__raw_writel(val, PLL8_ENET);
+
+	return _clk_enable(clk);
+}
+
+static void sata_clk_disable(struct clk *clk)
+{
+	u32 val;
+
+	_clk_disable(clk);
+
+	val = __raw_readl(PLL8_ENET);
+	val &= BM_PLL_ENET_EN_SATA;
+	__raw_writel(val, PLL8_ENET);
+}
+
+static struct clk sata_clk = {
+	.enable_reg = CCGR5,
+	.enable_shift = CG2,
+	.enable = sata_clk_enable,
+	.disable = sata_clk_disable,
+	.parent = &ipg_clk,
+	.secondary = &pll8_enet,
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	}
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("2020000.uart", NULL, uart_clk),
+	_REGISTER_CLOCK("21e8000.uart", NULL, uart_clk),
+	_REGISTER_CLOCK("21ec000.uart", NULL, uart_clk),
+	_REGISTER_CLOCK("21f0000.uart", NULL, uart_clk),
+	_REGISTER_CLOCK("21f4000.uart", NULL, uart_clk),
+	_REGISTER_CLOCK("2188000.enet", NULL, enet_clk),
+	_REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk),
+	_REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk),
+	_REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk),
+	_REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk),
+	_REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk),
+	_REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk),
+	_REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk),
+	_REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk),
+	_REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
+	_REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
+	_REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
+	_REGISTER_CLOCK(NULL, "ckih", ckih_clk),
+	_REGISTER_CLOCK(NULL, "ckih2_clk", ckih2_clk),
+	_REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
+	_REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
+	_REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk),
+	_REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk),
+	_REGISTER_CLOCK(NULL, "can2_clk", can2_clk),
+	_REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk),
+	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
+	_REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk),
+	_REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
+	_REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk),
+	_REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk),
+	_REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk),
+	_REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk),
+	_REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
+	_REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
+	_REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
+};
+
+static void __init imx6q_ccm_low_power_init(void)
+{
+	u32 val;
+
+	/* only keep necessary clocks on */
+	__raw_writel(0x3 << CG0  | 0x3 << CG1  | 0x3 << CG2,	CCGR0);
+	__raw_writel(0x3 << CG8  | 0x3 << CG9  | 0x3 << CG10,	CCGR2);
+	__raw_writel(0x3 << CG10 | 0x3 << CG12,			CCGR3);
+	__raw_writel(0x3 << CG4  | 0x3 << CG6  | 0x3 << CG7,	CCGR4);
+	__raw_writel(0x3 << CG0,				CCGR5);
+	__raw_writel(0,						CCGR6);
+	__raw_writel(0,						CCGR7);
+
+	clk_enable(&uart_clk);
+	clk_enable(&mmdc_ch0_axi_clk);
+
+	/* setup for STOP mode */
+	val = __raw_readl(CLPCR);
+	val &= ~(BM_CLPCR_LPM | BM_CLPCR_STBY_COUNT);
+	val |= 0x2 << BP_CLPCR_LPM | 0x3 << BP_CLPCR_STBY_COUNT;
+	val |= BM_CLPCR_VSTBY;
+	val |= BM_CLPCR_SBYOS;
+	val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+	__raw_writel(val, CLPCR);
+}
+
+static struct map_desc imx6q_clock_desc[] = {
+	{
+		.virtual	= MX6Q_CCM_BASE_VADDR,
+		.pfn		= __phys_to_pfn(MX6Q_CCM_BASE_ADDR),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MX6Q_ANATOP_BASE_VADDR,
+		.pfn		= __phys_to_pfn(MX6Q_ANATOP_BASE_ADDR),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+int __init mx6q_clocks_init(unsigned long ckil, unsigned long osc,
+			    unsigned long ckih1, unsigned long ckih2)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int i, irq;
+
+	iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
+
+	external_low_reference = ckil;
+	external_high_reference = ckih1;
+	ckih2_reference = ckih2;
+	oscillator_reference = osc;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	imx6q_ccm_low_power_init();
+
+	clk_set_rate(&pll4_audio, FREQ_650M);
+	clk_set_rate(&pll5_video, FREQ_650M);
+	clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk);
+	clk_set_parent(&ipu1_di0_pre_clk, &pll5_video);
+	clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m);
+	clk_set_rate(&gpu3d_shader_clk, FREQ_594M);
+	clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk);
+	clk_set_rate(&gpu3d_core_clk, FREQ_528M);
+	clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
+	clk_set_rate(&asrc_serial_clk, 1500000);
+	clk_set_rate(&enfc_clk, 11000000);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+	irq = irq_of_parse_and_map(np, 0);
+	mxc_timer_init(&gpt_clk, base, irq);
+
+	return 0;
+}
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
new file mode 100644
index 0000000..acf0ef7
--- /dev/null
+++ b/arch/arm/mach-imx/gpc.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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@the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/hardware/gic.h>
+
+#define GPC_IMR1		0x008
+#define GPC_PGC_CPU_PDN		0x2a0
+
+#define IMR_NUM			4
+
+static void __iomem *gpc_base;
+static u32 gpc_wake_irqs[IMR_NUM];
+static u32 gpc_saved_imrs[IMR_NUM];
+
+void imx_gpc_pre_suspend(void)
+{
+	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+	int i;
+
+	for (i = 0; i < IMR_NUM; i++) {
+		gpc_saved_imrs[i] = __raw_readl(reg_imr1 + i * 4);
+		__raw_writel(~gpc_wake_irqs[i], reg_imr1 + i * 4);
+	}
+
+	/* Tell GPC to power off ARM core when suspend */
+	__raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN);
+}
+
+void imx_gpc_post_resume(void)
+{
+	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+	int i;
+
+	for (i = 0; i < IMR_NUM; i++)
+		__raw_writel(gpc_saved_imrs[i], reg_imr1 + i * 4);
+}
+
+static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	unsigned int idx = d->irq / 32 - 1;
+	u32 mask;
+
+	/* Sanity check for SPI irq */
+	if (d->irq < 32)
+		return -EINVAL;
+
+	mask = 1 << d->irq % 32;
+	gpc_wake_irqs[idx] = on ? gpc_wake_irqs[idx] | mask :
+				  gpc_wake_irqs[idx] & ~mask;
+
+	return 0;
+}
+
+static void imx_gpc_irq_unmask(struct irq_data *d)
+{
+	void __iomem *reg;
+	u32 val;
+
+	/* Sanity check for SPI irq */
+	if (d->irq < 32)
+		return;
+
+	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	val = __raw_readl(reg);
+	val &= ~(1 << d->irq % 32);
+	__raw_writel(val, reg);
+}
+
+static void imx_gpc_irq_mask(struct irq_data *d)
+{
+	void __iomem *reg;
+	u32 val;
+
+	/* Sanity check for SPI irq */
+	if (d->irq < 32)
+		return;
+
+	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	val = __raw_readl(reg);
+	val |= 1 << (d->irq % 32);
+	__raw_writel(val, reg);
+}
+
+void __init imx_gpc_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
+	gpc_base = of_iomap(np, 0);
+	WARN_ON(!gpc_base);
+
+	/* Register GPC as the secondary interrupt controller behind GIC */
+	gic_arch_extn.irq_mask = imx_gpc_irq_mask;
+	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
+	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
+}
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
new file mode 100644
index 0000000..8d6b540
--- /dev/null
+++ b/arch/arm/mach-imx/mmdc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+
+#define MMDC_MAPSR		0x404
+#define BP_MMDC_MAPSR_PSD	0
+#define BP_MMDC_MAPSR_PSS	4
+
+static int __devinit imx_mmdc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	void __iomem *mmdc_base, *reg;
+	u32 val;
+	int timeout = 0x400;
+
+	mmdc_base = of_iomap(np, 0);
+	WARN_ON(!mmdc_base);
+
+	reg = mmdc_base + MMDC_MAPSR;
+
+	/* Enable automatic power saving */
+	val = readl(reg);
+	val &= ~(1 << BP_MMDC_MAPSR_PSD);
+	writel(val, reg);
+
+	/* Ensure it's successfully enabled */
+	while (!(readl(reg) & 1 << BP_MMDC_MAPSR_PSS) && --timeout)
+		cpu_relax();
+
+	if (unlikely(!timeout)) {
+		pr_warn("%s: failed to enable automatic power saving\n",
+			__func__);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static struct of_device_id imx_mmdc_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-mmdc", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver imx_mmdc_driver = {
+	.driver		= {
+		.name	= "imx-mmdc",
+		.owner	= THIS_MODULE,
+		.of_match_table = imx_mmdc_dt_ids,
+	},
+	.probe		= imx_mmdc_probe,
+};
+
+static int __init imx_mmdc_init(void)
+{
+	return platform_driver_register(&imx_mmdc_driver);
+}
+postcore_initcall(imx_mmdc_init);
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
new file mode 100644
index 0000000..95fdd65
--- /dev/null
+++ b/arch/arm/mach-imx/src.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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@the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/unified.h>
+
+#define SRC_SCR				0x000
+#define SRC_GPR1			0x020
+#define BP_SRC_SCR_CORE1_RST		14
+#define BP_SRC_SCR_CORE1_ENABLE		22
+
+static void __iomem *src_base;
+
+void imx_enable_cpu(int cpu, bool enable)
+{
+	u32 mask, val;
+
+	mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
+	val = __raw_readl(src_base + SRC_SCR);
+	val = enable ? val | mask : val & ~mask;
+	__raw_writel(val, src_base + SRC_SCR);
+}
+
+void imx_set_cpu_jump(int cpu, void *jump_addr)
+{
+	__raw_writel(BSYM(virt_to_phys(jump_addr)),
+		     src_base + SRC_GPR1 + cpu * 8);
+}
+
+static int __init imx_src_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
+	src_base = of_iomap(np, 0);
+	WARN_ON(!src_base);
+
+	return 0;
+}
+early_initcall(imx_src_init);
-- 
1.7.4.1

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

* [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
                   ` (2 preceding siblings ...)
  2011-09-06  9:58 ` [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 18:53   ` Arnd Bergmann
  2011-09-06  9:58 ` [PATCH 5/6] arm/imx6q: add device tree machine support Shawn Guo
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds smp and cpu hotplug support for imx6q.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Kconfig               |    1 +
 arch/arm/mach-imx/Makefile              |    4 ++
 arch/arm/mach-imx/head-v7.S             |   75 +++++++++++++++++++++++++++
 arch/arm/mach-imx/hotplug.c             |   44 ++++++++++++++++
 arch/arm/mach-imx/localtimer.c          |   64 +++++++++++++++++++++++
 arch/arm/mach-imx/platsmp.c             |   86 +++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/common.h |    3 +
 7 files changed, 277 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/head-v7.S
 create mode 100644 arch/arm/mach-imx/hotplug.c
 create mode 100644 arch/arm/mach-imx/localtimer.c
 create mode 100644 arch/arm/mach-imx/platsmp.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 30f2868..13e0301 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -72,6 +72,7 @@ config SOC_IMX6Q
 	bool
 	select ARM_GIC
 	select CPU_V7
+	select HAVE_ARM_SCU
 	select HAVE_IMX_GPC
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 8c21fda..d46b2e7 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -66,4 +66,8 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
 obj-$(CONFIG_HAVE_IMX_SRC) += src.o
+obj-$(CONFIG_CPU_V7) += head-v7.o
+obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/head-v7.S
new file mode 100644
index 0000000..001ff9e
--- /dev/null
+++ b/arch/arm/mach-imx/head-v7.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/linkage.h>
+#include <linux/init.h>
+
+	.section ".text.head", "ax"
+	__CPUINIT
+
+/*
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the main
+ * processor.  We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ *
+ * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
+ * to be called for both secondary cores startup and primary core resume
+ * procedures.  Ideally, it should be moved into arch/arm/mm/cache-v7.S.
+ */
+ENTRY(v7_invalidate_l1)
+	mov	r0, #0
+	mcr	p15, 2, r0, c0, c0, 0
+	mrc	p15, 1, r0, c0, c0, 0
+
+	ldr	r1, =0x7fff
+	and	r2, r1, r0, lsr #13
+
+	ldr	r1, =0x3ff
+
+	and	r3, r1, r0, lsr #3	@ NumWays - 1
+	add	r2, r2, #1		@ NumSets
+
+	and	r0, r0, #0x7
+	add	r0, r0, #4	@ SetShift
+
+	clz	r1, r3		@ WayShift
+	add	r4, r3, #1	@ NumWays
+1:	sub	r2, r2, #1	@ NumSets--
+	mov	r3, r4		@ Temp = NumWays
+2:	subs	r3, r3, #1	@ Temp--
+	mov	r5, r3, lsl r1
+	mov	r6, r2, lsl r0
+	orr	r5, r5, r6	@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+	mcr	p15, 0, r5, c7, c6, 2
+	bgt	2b
+	cmp	r2, #0
+	bgt	1b
+	dsb
+	isb
+	mov	pc, lr
+ENDPROC(v7_invalidate_l1)
+
+ENTRY(v7_cpu_resume)
+	bl	v7_invalidate_l1
+	b	cpu_resume
+ENDPROC(v7_cpu_resume)
+
+#ifdef CONFIG_SMP
+ENTRY(v7_secondary_startup)
+	bl	v7_invalidate_l1
+	b	secondary_startup
+ENDPROC(v7_secondary_startup)
+#endif
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
new file mode 100644
index 0000000..89493ab
--- /dev/null
+++ b/arch/arm/mach-imx/hotplug.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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@the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <asm/cacheflush.h>
+#include <mach/common.h>
+
+int platform_cpu_kill(unsigned int cpu)
+{
+	return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+	flush_cache_all();
+	imx_enable_cpu(cpu, false);
+	cpu_do_idle();
+
+	/* We should never return from idle */
+	panic("cpu %d unexpectedly exit from shutdown\n", cpu);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+	/*
+	 * we don't allow CPU 0 to be shutdown (it is still too special
+	 * e.g. clock tick interrupts)
+	 */
+	return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-imx/localtimer.c b/arch/arm/mach-imx/localtimer.c
new file mode 100644
index 0000000..2b0f351
--- /dev/null
+++ b/arch/arm/mach-imx/localtimer.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/clockchips.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
+
+static u32 twd_saved_regs[4];
+static int twd_irq;
+
+/*
+ * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
+ * re-setup local timer for secondary cores.  For primary core, it
+ * has to take care of itself with the following pair of functions
+ * during suspend/resume.
+ */
+void imx_local_timer_pre_suspend(void)
+{
+	twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
+	twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
+	twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
+	twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
+}
+
+void imx_local_timer_post_resume(void)
+{
+	__raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
+	__raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
+	__raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
+	__raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
+
+	gic_enable_ppi(twd_irq);
+}
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
+	if (!twd_base) {
+		twd_base = of_iomap(np, 0);
+		WARN_ON(!twd_base);
+	}
+	twd_irq = irq_of_parse_and_map(np, 0);
+	evt->irq = twd_irq;
+	twd_timer_setup(evt);
+
+	return 0;
+}
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
new file mode 100644
index 0000000..2352caf
--- /dev/null
+++ b/arch/arm/mach-imx/platsmp.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/smp.h>
+#include <asm/page.h>
+#include <asm/smp_scu.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+
+extern void v7_secondary_startup(void);
+
+#define IMX_SCU_VIRT_BASE	0xf4a00000
+
+static void __iomem *scu_base = ((void __iomem *)(IMX_SCU_VIRT_BASE));
+
+static struct map_desc scu_io_desc __initdata = {
+	.virtual	= IMX_SCU_VIRT_BASE,
+	.pfn		= 0, /* run-time */
+	.length		= SZ_4K,
+	.type		= MT_DEVICE,
+};
+
+void __init imx_scu_map_io(void)
+{
+	unsigned long base;
+
+	/* Get SCU base */
+	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
+
+	scu_io_desc.pfn = __phys_to_pfn(base);
+	iotable_init(&scu_io_desc, 1);
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_secondary_init(0);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	imx_set_cpu_jump(cpu, v7_secondary_startup);
+	imx_enable_cpu(cpu, true);
+	return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	int i, ncores;
+
+	ncores = scu_get_core_count(scu_base);
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
+}
+
+void imx_smp_prepare(void)
+{
+	scu_enable(scu_base);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+	imx_smp_prepare();
+}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 4e3d978..73da910 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -72,4 +72,7 @@ extern void mxc_arch_reset_init(void __iomem *);
 extern void mx51_efikamx_reset(void);
 extern int mx53_revision(void);
 extern int mx53_display_revision(void);
+
+extern void imx_enable_cpu(int cpu, bool enable);
+extern void imx_set_cpu_jump(int cpu, void *jump_addr);
 #endif
-- 
1.7.4.1

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

* [PATCH 5/6] arm/imx6q: add device tree machine support
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
                   ` (3 preceding siblings ...)
  2011-09-06  9:58 ` [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 18:55   ` Arnd Bergmann
  2011-09-06  9:58 ` [PATCH 6/6] arm/imx6q: add suspend/resume support Shawn Guo
  2011-09-06 18:28 ` [PATCH 0/6] add initial imx6q support Arnd Bergmann
  6 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds generic device tree based machine support for imx6q.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Kconfig               |   13 +++++
 arch/arm/mach-imx/Makefile              |    1 +
 arch/arm/mach-imx/mach-imx6q.c          |   81 +++++++++++++++++++++++++++++++
 arch/arm/mm/Kconfig                     |    2 +-
 arch/arm/plat-mxc/include/mach/common.h |   13 +++++
 5 files changed, 109 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-imx/mach-imx6q.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 13e0301..3364b59 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -624,3 +624,16 @@ config MACH_VPR200
 	  configurations for the board and its peripherals.
 
 endif
+
+if ARCH_MX6
+comment "i.MX6 machines:"
+
+config MACH_IMX6Q
+	bool "Support i.MX6 Quad platforms from device tree"
+	select SOC_IMX6Q
+	select USE_OF
+	help
+	  Include support for Freescale i.MX6 Quad based platforms
+	  using the device tree for discovery
+
+endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d46b2e7..84bd18c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_SMP) += platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o
+obj-$(CONFIG_MACH_IMX6Q) += mach-imx6q.o
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
new file mode 100644
index 0000000..b55f972
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+static void __init imx6q_init_machine(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void __init imx6q_map_io(void)
+{
+	imx_lluart_map_io();
+	imx_scu_map_io();
+}
+
+static void __init imx6q_init_irq(void)
+{
+	struct device_node *np;
+	struct of_intc_desc desc;
+	int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
+
+	l2x0_of_init(0, ~0UL);
+
+	memset(&desc, 0, sizeof(desc));
+	desc.controller = of_find_compatible_node(NULL, NULL,
+						  "arm,cortex-a9-gic");
+	gic_of_init(&desc);
+	imx_gpc_init();
+
+	np = desc.controller;
+	for_each_child_of_node(np, desc.controller)
+		gic_of_ppi_init(&desc);
+
+	for_each_compatible_node(np, NULL, "fsl,imx6q-gpio") {
+		gpio_irq_base -= 32;
+		irq_domain_add_simple(np, gpio_irq_base);
+	}
+}
+
+static void __init imx6q_timer_init(void)
+{
+	mx6q_clocks_init(32768, 24000000, 0, 0);
+}
+
+static struct sys_timer imx6q_timer = {
+	.init = imx6q_timer_init,
+};
+
+static const char *imx6q_dt_compat[] __initdata = {
+	"fsl,imx6q-sabreauto",
+	NULL,
+};
+
+DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
+	.map_io		= imx6q_map_io,
+	.init_irq	= imx6q_init_irq,
+	.timer		= &imx6q_timer,
+	.init_machine	= imx6q_init_machine,
+	.dt_compat	= imx6q_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 88633fe..c3ce146 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -822,7 +822,7 @@ config CACHE_L2X0
 		   REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \
 		   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
 		   ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \
-		   ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX
+		   ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_MX6
 	default y
 	select OUTER_CACHE
 	select OUTER_CACHE_SYNC
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 73da910..ff86063 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -64,6 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
 			unsigned long ckih1, unsigned long ckih2);
 extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
 			unsigned long ckih1, unsigned long ckih2);
+extern int mx6q_clocks_init(unsigned long ckil, unsigned long osc,
+			unsigned long ckih1, unsigned long ckih2);
 extern struct platform_device *mxc_register_gpio(char *name, int id,
 	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
@@ -73,6 +75,17 @@ extern void mx51_efikamx_reset(void);
 extern int mx53_revision(void);
 extern int mx53_display_revision(void);
 
+#ifdef CONFIG_DEBUG_LL
+extern void imx_lluart_map_io(void);
+#else
+static inline void imx_lluart_map_io(void) {}
+#endif
+#ifdef CONFIG_SMP
+extern void imx_scu_map_io(void);
+#else
+static inline void imx_scu_map_io(void) {}
+#endif
 extern void imx_enable_cpu(int cpu, bool enable);
 extern void imx_set_cpu_jump(int cpu, void *jump_addr);
+extern void imx_gpc_init(void);
 #endif
-- 
1.7.4.1

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
                   ` (4 preceding siblings ...)
  2011-09-06  9:58 ` [PATCH 5/6] arm/imx6q: add device tree machine support Shawn Guo
@ 2011-09-06  9:58 ` Shawn Guo
  2011-09-06 18:56   ` Arnd Bergmann
  2011-09-07 13:50   ` Barry Song
  2011-09-06 18:28 ` [PATCH 0/6] add initial imx6q support Arnd Bergmann
  6 siblings, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-06  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

It adds suspend/resume support for imx6q.

Signed-off-by: Anson Huang <b20788@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Makefile              |    2 +-
 arch/arm/mach-imx/pm-imx6q.c            |   63 +++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/common.h |   12 ++++++
 3 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-imx/pm-imx6q.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 84bd18c..531da76 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -70,5 +70,5 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
 obj-$(CONFIG_SMP) += platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
-obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o
+obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o pm-imx6q.o
 obj-$(CONFIG_MACH_IMX6Q) += mach-imx6q.o
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
new file mode 100644
index 0000000..cbbc3c8
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <linux/init.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <mach/common.h>
+
+static int imx6q_suspend_finish(unsigned long val)
+{
+	cpu_do_idle();
+	return 0;
+}
+
+static int imx6q_pm_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		imx_local_timer_pre_suspend();
+		imx_gpc_pre_suspend();
+		outer_flush_all();
+		outer_disable();
+		imx_set_cpu_jump(0, v7_cpu_resume);
+
+		/* Zzz ... */
+		cpu_suspend(0, imx6q_suspend_finish);
+
+		imx_smp_prepare();
+		l2x0_of_init(0, ~0UL);
+		imx_gpc_post_resume();
+		imx_local_timer_post_resume();
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct platform_suspend_ops imx6q_pm_ops = {
+	.enter = imx6q_pm_enter,
+	.valid = suspend_valid_only_mem,
+};
+
+static int __init imx6q_pm_init(void)
+{
+	suspend_set_ops(&imx6q_pm_ops);
+	return 0;
+}
+late_initcall(imx6q_pm_init);
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index ff86063..7c3d078 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -80,12 +80,24 @@ extern void imx_lluart_map_io(void);
 #else
 static inline void imx_lluart_map_io(void) {}
 #endif
+extern void v7_cpu_resume(void);
 #ifdef CONFIG_SMP
 extern void imx_scu_map_io(void);
+extern void imx_smp_prepare(void);
 #else
 static inline void imx_scu_map_io(void) {}
+static inline void imx_smp_prepare(void) {}
 #endif
 extern void imx_enable_cpu(int cpu, bool enable);
 extern void imx_set_cpu_jump(int cpu, void *jump_addr);
 extern void imx_gpc_init(void);
+extern void imx_gpc_pre_suspend(void);
+extern void imx_gpc_post_resume(void);
+#ifdef CONFIG_LOCAL_TIMERS
+extern void imx_local_timer_pre_suspend(void);
+extern void imx_local_timer_post_resume(void);
+#else
+static inline void imx_local_timer_pre_suspend(void) {}
+static inline void imx_local_timer_post_resume(void) {}
+#endif
 #endif
-- 
1.7.4.1

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

* [PATCH 0/6] add initial imx6q support
  2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
                   ` (5 preceding siblings ...)
  2011-09-06  9:58 ` [PATCH 6/6] arm/imx6q: add suspend/resume support Shawn Guo
@ 2011-09-06 18:28 ` Arnd Bergmann
  2011-09-06 19:42   ` Uwe Kleine-König
  2011-09-07  2:51   ` Shawn Guo
  6 siblings, 2 replies; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:34 Shawn Guo wrote:
> This patch series adds the initial support for imx6q, which is a
> Cortex-A9 MPCore (4 cores) SoC.
> 
> It's based on v3.1-rc4 with the patches below applied.
> 
>  * [PATCH v2 0/5] Convert DEBUG_LL UART selection to a Kconfig choice
>    http://thread.gmane.org/gmane.linux.ports.arm.kernel/129702
> 
>  * [PATCH v4 2/2] ARM: l2x0: Add OF based initialization
>    http://article.gmane.org/gmane.linux.kernel/1164401
> 
>  * [PATCH 1/7] ARM: l2x0: add empty l2x0_of_init
>    http://article.gmane.org/gmane.linux.ports.arm.kernel/130878
> 
>  * [RFC PATCH 0/3] Yet another GIC OF binding series
>    http://thread.gmane.org/gmane.linux.drivers.devicetree/7226
> 
> For suspend/resume support, it needs the following extra patches
> applied.
> 
>  * [PATCH v2 0/2] make reinitialization of ARM core components possible
>    http://thread.gmane.org/gmane.linux.ports.arm.kernel/131356
> 
>  * [PATCH v2 0/5] CPU PM notifiers
>    http://thread.gmane.org/gmane.linux.ports.arm.kernel/131212/focus=131353

Hi Shawn,

We've talked about it before, but I don't remember the outcome. Can you
explain (and add to the above text) a short explanation of why this is
in the mach-imx directory, rather than the mach-mx5 (which probably is
closer to mx6 than mx3 is) or a new mach-mx6?

	Arnd

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

* [PATCH 1/6] arm/imx6q: add device tree source
  2011-09-06  9:58 ` [PATCH 1/6] arm/imx6q: add device tree source Shawn Guo
@ 2011-09-06 18:31   ` Arnd Bergmann
  2011-09-07 11:16     ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:35 Shawn Guo wrote:
> +
> +       aips-bus at 02000000 { /* AIPS1 */
> +               compatible = "fsl,aips-bus", "simple-bus";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               reg = <0x02000000 0x100000>;
> +               ranges;
> +
> +               spba-bus at 02000000 {
> +                       compatible = "fsl,spba-bus", "simple-bus";
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       reg = <0x02000000 0x40000>;
> +                       ranges;

Wouldn't it be better to have the ranges property translate bus-local addresses
to global addresses, rather than having an empty ranges property?

	Arnd

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06  9:58 ` [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart Shawn Guo
@ 2011-09-06 18:39   ` Arnd Bergmann
  2011-09-07  8:50     ` Shawn Guo
  2011-09-06 20:25   ` Uwe Kleine-König
  1 sibling, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:36 Shawn Guo wrote:
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> @@ -0,0 +1,29 @@
> +#ifndef __MACH_MX6Q_H__
> +#define __MACH_MX6Q_H__
> +
> +/* static mappings */
> +#define IMX6Q_VA(x)            (0xf4000000 + (x))

This should return a 'void __iomem *' pointer, not an integer.

> +#define MX6Q_SCU_BASE_ADDR     0x00a00000
> +#define MX6Q_CCM_BASE_ADDR     0x020c4000
> +#define MX6Q_ANATOP_BASE_ADDR  0x020c8000
> +#define MX6Q_UART4_BASE_ADDR   0x021f0000
> +
> +#define MX6Q_SCU_BASE_VADDR    IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> +#define MX6Q_CCM_BASE_VADDR    IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> +#define MX6Q_ANATOP_BASE_VADDR IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> +#define MX6Q_UART4_BASE_VADDR  IMX6Q_VA(MX6Q_UART4_BASE_ADDR)

The list is reasonably short, but I think you can still try harder to remove
some of the remaining elements. I can understand the need for UART4
(for ll_debug), but I don't really understand what the others are and
why you cannot get the values from the device tree and ioremap them.

Maybe you can add a few comments to explain these if they are indeed
necessary.

	Arnd

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

* [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support
  2011-09-06  9:58 ` [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support Shawn Guo
@ 2011-09-06 18:53   ` Arnd Bergmann
  2011-09-07  4:41     ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:38 Shawn Guo wrote:
> It adds smp and cpu hotplug support for imx6q.
> +static u32 twd_saved_regs[4];
> +static int twd_irq;
> +
> +/*
> + * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
> + * re-setup local timer for secondary cores.  For primary core, it
> + * has to take care of itself with the following pair of functions
> + * during suspend/resume.
> + */
> +void imx_local_timer_pre_suspend(void)
> +{
> +	twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
> +	twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
> +	twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
> +	twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
> +}
> +
> +void imx_local_timer_post_resume(void)
> +{
> +	__raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
> +	__raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
> +	__raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
> +	__raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
> +
> +	gic_enable_ppi(twd_irq);
> +}

readl_relaxed()?

> +extern void v7_secondary_startup(void);
> +
> +#define IMX_SCU_VIRT_BASE	0xf4a00000
> +
> +static void __iomem *scu_base = ((void __iomem *)(IMX_SCU_VIRT_BASE));

It's a little bit silly to have a variable for the base and then initialize
it statically. Not sure what the best solution is here.

> +static struct map_desc scu_io_desc __initdata = {
> +	.virtual	= IMX_SCU_VIRT_BASE,
> +	.pfn		= 0, /* run-time */
> +	.length		= SZ_4K,
> +	.type		= MT_DEVICE,
> +};
> +
> +void __init imx_scu_map_io(void)
> +{
> +	unsigned long base;
> +
> +	/* Get SCU base */
> +	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
> +
> +	scu_io_desc.pfn = __phys_to_pfn(base);
> +	iotable_init(&scu_io_desc, 1);
> +}

Maybe we can simply define a platform-independent where the SCU gets mapped?
That would get rid of most of the platform specific SCU code, at least for
those platforms that can reliably read the scu base.

> +/*
> + * Initialise the CPU possible map early - this describes the CPUs
> + * which may be present or become present in the system.
> + */
> +void __init smp_init_cpus(void)
> +{
> +	int i, ncores;
> +
> +	ncores = scu_get_core_count(scu_base);
> +
> +	for (i = 0; i < ncores; i++)
> +		set_cpu_possible(i, true);
> +
> +	set_smp_cross_call(gic_raise_softirq);
> +}
> +
> +void imx_smp_prepare(void)
> +{
> +	scu_enable(scu_base);
> +}
> +
> +void __init platform_smp_prepare_cpus(unsigned int max_cpus)
> +{
> +	imx_smp_prepare();
> +}

Then these functions could also be moved into the smp_scu file as generic
helpers that can be used by all similar platforms.

	Arnd

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

* [PATCH 5/6] arm/imx6q: add device tree machine support
  2011-09-06  9:58 ` [PATCH 5/6] arm/imx6q: add device tree machine support Shawn Guo
@ 2011-09-06 18:55   ` Arnd Bergmann
  2011-09-07  3:07     ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:39 Shawn Guo wrote:

> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 13e0301..3364b59 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -624,3 +624,16 @@ config MACH_VPR200
>  	  configurations for the board and its peripherals.
>  
>  endif
> +
> +if ARCH_MX6
> +comment "i.MX6 machines:"
> +
> +config MACH_IMX6Q
> +	bool "Support i.MX6 Quad platforms from device tree"
> +	select SOC_IMX6Q
> +	select USE_OF
> +	help
> +	  Include support for Freescale i.MX6 Quad based platforms
> +	  using the device tree for discovery
> +
> +endif

As we have done on zynq and prima2, I would suggest not to add multiple
machines types at all. You already have the intialization in a generic
imx6q file, it would be logical to get rid of the configuration entry
as well.

What you can still have is config options for optional drivers that
might be needed for one soc but not another.

	Arnd

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-06  9:58 ` [PATCH 6/6] arm/imx6q: add suspend/resume support Shawn Guo
@ 2011-09-06 18:56   ` Arnd Bergmann
  2011-09-07 13:50   ` Barry Song
  1 sibling, 0 replies; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:40 Shawn Guo wrote:
> It adds suspend/resume support for imx6q.
> 
> Signed-off-by: Anson Huang <b20788@freescale.com>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

Ah, no assembler code in there. Very nice!

	Arnd

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-06  9:58 ` [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src Shawn Guo
@ 2011-09-06 19:14   ` Arnd Bergmann
  2011-09-07  6:05     ` Shawn Guo
  2011-09-12  9:46   ` Sascha Hauer
  1 sibling, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-06 19:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 06 September 2011 17:58:37 Shawn Guo wrote:
> It adds a number of core drivers support for imx6q, including clock,
> General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
> System Reset Controller (src).
> 
> Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  arch/arm/mach-imx/Kconfig       |   13 +
>  arch/arm/mach-imx/Makefile      |    4 +
>  arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-imx/gpc.c         |  110 +++
>  arch/arm/mach-imx/mmdc.c        |   71 ++
>  arch/arm/mach-imx/src.c         |   52 +
>  6 files changed, 2240 insertions(+), 0 deletions(-)

This is unfortunately still a major problem. I realize that we don't
yet have a good framework to do this with significantly less code,
but adding a platform that is mostly consisting of stupid additions
of clock descriptions that really should be in the device tree does
not scale much longer. We decided to let this still get in for prima2,
which was also ugly in this regard but much simpler than imx6.

My feeling is that this time, we should wait for the common clock
framework to get in and simplify this. I believe Thomas is now planning
to do this, but I haven't followed what the current state is.

The other three drivers in this patch are basically ok, so you can
definitely post them as a separate patch and perhaps get minor comments
for those, similar to what I commented on the other patches.

For the clock-imx6q.c file, what I first want to hear from someone
is how this is supposed to look like in the long run with device tree
integration, and how far away from that we are.

Can you comment on how far we get without the clock driver with imx6?
Is is basically useless, or is there a way we can merge the remaining
imx6 code and other drivers but postpone the large clock driver?

	Arnd

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

* [PATCH 0/6] add initial imx6q support
  2011-09-06 18:28 ` [PATCH 0/6] add initial imx6q support Arnd Bergmann
@ 2011-09-06 19:42   ` Uwe Kleine-König
  2011-09-07  2:55     ` Shawn Guo
  2011-09-07  2:51   ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Uwe Kleine-König @ 2011-09-06 19:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Arnd,

On Tue, Sep 06, 2011 at 08:28:39PM +0200, Arnd Bergmann wrote:
> We've talked about it before, but I don't remember the outcome. Can you
> explain (and add to the above text) a short explanation of why this is
> in the mach-imx directory, rather than the mach-mx5 (which probably is
> closer to mx6 than mx3 is) or a new mach-mx6?
Not having looked into the patches yet, but I think mach-imx is the
right choice. The longterm plan for mach-mx5 is to be folded into
mach-imx, too. We just didn't found a volunteer for that.

Best regards
Uwe

BTW, are you on irc somewhere?

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06  9:58 ` [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart Shawn Guo
  2011-09-06 18:39   ` Arnd Bergmann
@ 2011-09-06 20:25   ` Uwe Kleine-König
  2011-09-07 11:00     ` Shawn Guo
  2011-09-15  1:24     ` Shawn Guo
  1 sibling, 2 replies; 69+ messages in thread
From: Uwe Kleine-König @ 2011-09-06 20:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> It adds the core definitions and low-level debug uart support
> for imx6q.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  arch/arm/Kconfig                             |    2 +-
>  arch/arm/Kconfig.debug                       |    7 +++++
>  arch/arm/Makefile                            |    1 +
>  arch/arm/mach-imx/Kconfig                    |    4 +++
>  arch/arm/mach-imx/Makefile                   |    2 +
>  arch/arm/mach-imx/Makefile.boot              |    4 +++
>  arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
>  arch/arm/plat-mxc/Kconfig                    |    5 ++++
>  arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
>  arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
>  arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
>  arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
>  arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
>  arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
>  14 files changed, 115 insertions(+), 5 deletions(-)
>  create mode 100644 arch/arm/mach-imx/lluart.c
>  create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 4ea9974..37c20a4 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1348,7 +1348,7 @@ config SMP
>  	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
>  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
>  		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
> -		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
> +		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
>  	select USE_GENERIC_SMP_HELPERS
>  	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
>  	help
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index 965d59a..68fc155 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -155,6 +155,13 @@ choice
>  		  Say Y here if you want kernel low-level debugging support
>  		  on i.MX50 or i.MX53.
>  
> +	config DEBUG_IMX6Q_UART
> +		bool "i.MX6Q Debug UART"
> +		depends on SOC_IMX6Q
> +		help
> +		  Say Y here if you want kernel low-level debugging support
> +		  on i.MX6Q.
> +
>  	config DEBUG_S3C_UART0
>  		depends on PLAT_SAMSUNG
>  		bool "Use S3C UART 0 for low-level debug"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 70c424e..3a0bbe4 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
>  machine-$(CONFIG_ARCH_MX25)		:= imx
>  machine-$(CONFIG_ARCH_MX3)		:= imx
>  machine-$(CONFIG_ARCH_MX5)		:= mx5
> +machine-$(CONFIG_ARCH_MX6)		:= imx
>  machine-$(CONFIG_ARCH_MXS)		:= mxs
>  machine-$(CONFIG_ARCH_NETX)		:= netx
>  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 0519dd7..4cf5178 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -58,6 +58,10 @@ config SOC_IMX35
>  	select ARCH_MX35
>  	select MXC_AVIC
>  
> +config SOC_IMX6Q
> +	bool
> +	select ARM_GIC
> +	select CPU_V7
>  
>  if ARCH_MX1
>  
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index e9eb36d..96ecc96 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
>  obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
>  obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
>  obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> +
> +obj-$(CONFIG_DEBUG_LL) += lluart.o
> diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> index ebee18b..389a0e3 100644
> --- a/arch/arm/mach-imx/Makefile.boot
> +++ b/arch/arm/mach-imx/Makefile.boot
> @@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
>  zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
>  params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
>  initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
> +
> +zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
> +params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
> +initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
Do you really need params_phys and initrd_phys?

> diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
> new file mode 100644
> index 0000000..34205cb
> --- /dev/null
> +++ b/arch/arm/mach-imx/lluart.c
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc.
> + * Copyright 2011 Linaro Ltd.
> + *
> + * 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 <linux/init.h>
> +#include <asm/page.h>
> +#include <asm/sizes.h>
> +#include <asm/mach/map.h>
> +#include <mach/hardware.h>
> +
> +static struct map_desc imx_lluart_desc = {
> +#ifdef CONFIG_DEBUG_IMX6Q_UART
> +	.virtual	= MX6Q_UART4_BASE_VADDR,
> +	.pfn		= __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
> +	.length		= SZ_16K,
> +	.type		= MT_DEVICE,
> +#endif
> +};
> +
> +void __init imx_lluart_map_io(void)
> +{
> +	if (imx_lluart_desc.virtual)
> +		iotable_init(&imx_lluart_desc, 1);
> +}
I don't see yet where this is called, but I wonder what happens on a
non-imx6q machine (provided it is called there).
> +
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index a5353fc..e548f9b 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -48,6 +48,11 @@ config ARCH_MX51
>  	help
>  	  This enables support for systems based on the Freescale i.MX51 family
>  
> +config ARCH_MX6
> +	bool "i.MX6"
> +	help
> +	  This enables support for systems based on the Freescale i.MX6 family
> +
>  endchoice
>  
>  source "arch/arm/mach-imx/Kconfig"
> diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> index 07cfdbe..471872a 100644
> --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> @@ -24,9 +24,14 @@
>  #define UART_PADDR	MX51_UART1_BASE_ADDR
>  #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
>  #define UART_PADDR	MX53_UART1_BASE_ADDR
> +#elif defined (CONFIG_DEBUG_IMX6Q_UART)
> +#define UART_PADDR	MX6Q_UART4_BASE_ADDR
> +#define UART_VADDR	MX6Q_UART4_BASE_VADDR
You cannot use the existing IMX_IO_P2V? I'd like to have a look into it
to make it usable there, too. See below.

>  #endif
>  
> +#ifndef UART_VADDR
>  #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
> +#endif
>  
>  		.macro	addruart, rp, rv
>  		ldr	\rp, =UART_PADDR	@ physical
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index 066d464..341f800 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -1,6 +1,6 @@
>  /*
>   *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> - *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
>   */
>  
>  /*
> @@ -11,6 +11,17 @@
>  
>  #include <mach/hardware.h>
>  
> +#ifdef CONFIG_ARM_GIC
> +#include <asm/hardware/entry-macro-gic.S>
> +
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	arch_ret_to_user, tmp1, tmp2
> +	.endm
> +
> +#else
> +
hmm, this essentially means mx6 support cannot go into a kernel image
for the other imx machines :-(

>  #define AVIC_NIMASK	0x04
>  
>  	@ this macro disables fast irq (not implemented)
> @@ -78,3 +89,5 @@
>  	movs \irqnr, \irqnr
>  #endif
>  	.endm
> +
> +#endif /* CONFIG_ARM_GIC */
> diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> index a8bfd56..e1f84ce 100644
> --- a/arch/arm/plat-mxc/include/mach/hardware.h
> +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> @@ -97,6 +97,7 @@
>  
>  #include <mach/mxc.h>
>  
> +#include <mach/mx6q.h>
>  #include <mach/mx50.h>
>  #include <mach/mx51.h>
>  #include <mach/mx53.h>
> diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> index 00e812b..3ae400f 100644
> --- a/arch/arm/plat-mxc/include/mach/irqs.h
> +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> @@ -14,12 +14,15 @@
>  #include <asm-generic/gpio.h>
>  
>  /*
> - * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> + * SoCs with AVIC interrupt controller have 64 IRQs, those with TZIC
> + * have 128, otherwise those with GIC have 160 IRQs.
>   */
> -#ifdef CONFIG_MXC_TZIC
> +#if defined CONFIG_MXC_AVIC
> +#define MXC_INTERNAL_IRQS	64
> +#elif defined CONFIG_MXC_TZIC
>  #define MXC_INTERNAL_IRQS	128
>  #else
> -#define MXC_INTERNAL_IRQS	64
> +#define MXC_INTERNAL_IRQS	160
>  #endif
This is broken. The highest number has to go to the top. Otherwise if
you have an image with at least 2 of the available irq controllers your
MXC_INTERNAL_IRQS is too small.

>  
>  #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
> diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> index 11be5cd..2b8e186 100644
> --- a/arch/arm/plat-mxc/include/mach/memory.h
> +++ b/arch/arm/plat-mxc/include/mach/memory.h
> @@ -19,6 +19,7 @@
>  #define MX50_PHYS_OFFSET	UL(0x70000000)
>  #define MX51_PHYS_OFFSET	UL(0x90000000)
>  #define MX53_PHYS_OFFSET	UL(0x70000000)
> +#define MX6Q_PHYS_OFFSET	UL(0x10000000)
>  
>  #if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
>  # if defined CONFIG_ARCH_MX1
> @@ -37,6 +38,8 @@
>  #  define PLAT_PHYS_OFFSET		MX51_PHYS_OFFSET
>  # elif defined CONFIG_ARCH_MX53
>  #  define PLAT_PHYS_OFFSET		MX53_PHYS_OFFSET
> +# elif defined CONFIG_SOC_IMX6Q
> +#  define PLAT_PHYS_OFFSET		MX6Q_PHYS_OFFSET
>  # endif
>  #endif
>  
> diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> new file mode 100644
> index 0000000..7432310
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2011 Linaro Ltd.
> + *
> + * 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
> + */
> +
> +#ifndef __MACH_MX6Q_H__
> +#define __MACH_MX6Q_H__
> +
> +/* static mappings */
> +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> +
> +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> +
> +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
Depending on the sizes of these memory regions you can use the existing
IMX_IO_P2V here. The conditions are:

	SCU_SIZE <= 0x200000
	CCM_SIZE <= 0x4000
	ANATOP_SIZE <= 0x28000
	UART4 <= 0x100000

hmm, looking@patch 4 SCU_BASE is determined by a coprocessor
instruction?! Other than that these restrictions seem to be fulfilled.

Best regards
Uwe

> +
> +#endif	/* __MACH_MX6Q_H__ */
> -- 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 0/6] add initial imx6q support
  2011-09-06 18:28 ` [PATCH 0/6] add initial imx6q support Arnd Bergmann
  2011-09-06 19:42   ` Uwe Kleine-König
@ 2011-09-07  2:51   ` Shawn Guo
  1 sibling, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  2:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 08:28:39PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:34 Shawn Guo wrote:
> > This patch series adds the initial support for imx6q, which is a
> > Cortex-A9 MPCore (4 cores) SoC.
> > 
> > It's based on v3.1-rc4 with the patches below applied.
> > 
> >  * [PATCH v2 0/5] Convert DEBUG_LL UART selection to a Kconfig choice
> >    http://thread.gmane.org/gmane.linux.ports.arm.kernel/129702
> > 
> >  * [PATCH v4 2/2] ARM: l2x0: Add OF based initialization
> >    http://article.gmane.org/gmane.linux.kernel/1164401
> > 
> >  * [PATCH 1/7] ARM: l2x0: add empty l2x0_of_init
> >    http://article.gmane.org/gmane.linux.ports.arm.kernel/130878
> > 
> >  * [RFC PATCH 0/3] Yet another GIC OF binding series
> >    http://thread.gmane.org/gmane.linux.drivers.devicetree/7226
> > 
> > For suspend/resume support, it needs the following extra patches
> > applied.
> > 
> >  * [PATCH v2 0/2] make reinitialization of ARM core components possible
> >    http://thread.gmane.org/gmane.linux.ports.arm.kernel/131356
> > 
> >  * [PATCH v2 0/5] CPU PM notifiers
> >    http://thread.gmane.org/gmane.linux.ports.arm.kernel/131212/focus=131353
> 
> Hi Shawn,
> 
> We've talked about it before, but I don't remember the outcome. Can you
> explain (and add to the above text) a short explanation of why this is
> in the mach-imx directory, rather than the mach-mx5 (which probably is
> closer to mx6 than mx3 is) or a new mach-mx6?
> 
As Uwe mentioned, our long term view on imx sub-architecture is to move
mach-mx5 into mach-imx, so that we can have single mach folder for imx,
though whether we eventually move plat-mxc into mach-imx or not is
another thing we can think about later.

I will add something about that in the cover letter with the next post.

-- 
Regards,
Shawn

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

* [PATCH 0/6] add initial imx6q support
  2011-09-06 19:42   ` Uwe Kleine-König
@ 2011-09-07  2:55     ` Shawn Guo
  2011-09-07  9:39       ` Arnd Bergmann
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  2:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 09:42:53PM +0200, Uwe Kleine-K?nig wrote:
> Hello Arnd,
> 
> On Tue, Sep 06, 2011 at 08:28:39PM +0200, Arnd Bergmann wrote:
> > We've talked about it before, but I don't remember the outcome. Can you
> > explain (and add to the above text) a short explanation of why this is
> > in the mach-imx directory, rather than the mach-mx5 (which probably is
> > closer to mx6 than mx3 is) or a new mach-mx6?
> Not having looked into the patches yet, but I think mach-imx is the
> right choice. The longterm plan for mach-mx5 is to be folded into
> mach-imx, too. We just didn't found a volunteer for that.

My plan is to convert all the board files in mach-mx5 to imx51-dt.c
and imx53-dt.c first, and then merge the folder into mach-imx.

> 
> Best regards
> Uwe
> 
> BTW, are you on irc somewhere?
> 
I'm not sure this is a question for me or Arnd.  I'm usually on
#linaro-kernel.

-- 
Regards,
Shawn

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

* [PATCH 5/6] arm/imx6q: add device tree machine support
  2011-09-06 18:55   ` Arnd Bergmann
@ 2011-09-07  3:07     ` Shawn Guo
  2011-09-07  7:26       ` Arnd Bergmann
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  3:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 08:55:45PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:39 Shawn Guo wrote:
> 
> > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > index 13e0301..3364b59 100644
> > --- a/arch/arm/mach-imx/Kconfig
> > +++ b/arch/arm/mach-imx/Kconfig
> > @@ -624,3 +624,16 @@ config MACH_VPR200
> >  	  configurations for the board and its peripherals.
> >  
> >  endif
> > +
> > +if ARCH_MX6
> > +comment "i.MX6 machines:"
> > +
> > +config MACH_IMX6Q
> > +	bool "Support i.MX6 Quad platforms from device tree"
> > +	select SOC_IMX6Q
> > +	select USE_OF
> > +	help
> > +	  Include support for Freescale i.MX6 Quad based platforms
> > +	  using the device tree for discovery
> > +
> > +endif
> 
> As we have done on zynq and prima2, I would suggest not to add multiple
> machines types at all. You already have the intialization in a generic
> imx6q file, it would be logical to get rid of the configuration entry
> as well.
> 
This MACH_IMX6Q was added to make the IMX6Q Kconfig hierarchy look
consistent with other SoCs in arch/arm/mach-imx/Kconfig.  If you
do not like it, I can kill it.

-- 
Regards,
Shawn

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

* [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support
  2011-09-06 18:53   ` Arnd Bergmann
@ 2011-09-07  4:41     ` Shawn Guo
  2011-09-07  5:08       ` Shilimkar, Santosh
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  4:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 08:53:07PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:38 Shawn Guo wrote:
> > It adds smp and cpu hotplug support for imx6q.
> > +static u32 twd_saved_regs[4];
> > +static int twd_irq;
> > +
> > +/*
> > + * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
> > + * re-setup local timer for secondary cores.  For primary core, it
> > + * has to take care of itself with the following pair of functions
> > + * during suspend/resume.
> > + */
> > +void imx_local_timer_pre_suspend(void)
> > +{
> > +	twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
> > +	twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
> > +	twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
> > +	twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
> > +}
> > +
> > +void imx_local_timer_post_resume(void)
> > +{
> > +	__raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
> > +	__raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
> > +	__raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
> > +	__raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
> > +
> > +	gic_enable_ppi(twd_irq);
> > +}
> 
> readl_relaxed()?
> 
Ok.  You get the best judgement on this.

> > +extern void v7_secondary_startup(void);
> > +
> > +#define IMX_SCU_VIRT_BASE	0xf4a00000
> > +
> > +static void __iomem *scu_base = ((void __iomem *)(IMX_SCU_VIRT_BASE));
> 
> It's a little bit silly to have a variable for the base and then initialize
> it statically. Not sure what the best solution is here.
> 
I have to admit that this scu mapping code was cloned from highbank :)

> > +static struct map_desc scu_io_desc __initdata = {
> > +	.virtual	= IMX_SCU_VIRT_BASE,
> > +	.pfn		= 0, /* run-time */
> > +	.length		= SZ_4K,
> > +	.type		= MT_DEVICE,
> > +};
> > +
> > +void __init imx_scu_map_io(void)
> > +{
> > +	unsigned long base;
> > +
> > +	/* Get SCU base */
> > +	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
> > +
> > +	scu_io_desc.pfn = __phys_to_pfn(base);
> > +	iotable_init(&scu_io_desc, 1);
> > +}
> 
> Maybe we can simply define a platform-independent where the SCU gets mapped?
> That would get rid of most of the platform specific SCU code, at least for
> those platforms that can reliably read the scu base.
> 
Yes, if we can find a virtual base working for all platforms.  The scu
virtual base needs to be available before dynamic mapping gets ready,
so it has to be static mapping.

> > +/*
> > + * Initialise the CPU possible map early - this describes the CPUs
> > + * which may be present or become present in the system.
> > + */
> > +void __init smp_init_cpus(void)
> > +{
> > +	int i, ncores;
> > +
> > +	ncores = scu_get_core_count(scu_base);
> > +
> > +	for (i = 0; i < ncores; i++)
> > +		set_cpu_possible(i, true);
> > +
> > +	set_smp_cross_call(gic_raise_softirq);
> > +}
> > +
> > +void imx_smp_prepare(void)
> > +{
> > +	scu_enable(scu_base);
> > +}
> > +
> > +void __init platform_smp_prepare_cpus(unsigned int max_cpus)
> > +{
> > +	imx_smp_prepare();
> > +}
> 
> Then these functions could also be moved into the smp_scu file as generic
> helpers that can be used by all similar platforms.
> 

-- 
Regards,
Shawn

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

* [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support
  2011-09-07  4:41     ` Shawn Guo
@ 2011-09-07  5:08       ` Shilimkar, Santosh
  2011-09-07  7:46         ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Shilimkar, Santosh @ 2011-09-07  5:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 7, 2011 at 10:11 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
> On Tue, Sep 06, 2011 at 08:53:07PM +0200, Arnd Bergmann wrote:
>> On Tuesday 06 September 2011 17:58:38 Shawn Guo wrote:
>> > It adds smp and cpu hotplug support for imx6q.
>> > +static u32 twd_saved_regs[4];
>> > +static int twd_irq;
>> > +
>> > +/*
>> > + * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
>> > + * re-setup local timer for secondary cores. ?For primary core, it
>> > + * has to take care of itself with the following pair of functions
>> > + * during suspend/resume.
>> > + */
>> > +void imx_local_timer_pre_suspend(void)
>> > +{
>> > + ? twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
>> > + ? twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
>> > + ? twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
>> > + ? twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
>> > +}
>> > +
>> > +void imx_local_timer_post_resume(void)
>> > +{
>> > + ? __raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
>> > + ? __raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
>> > + ? __raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
>> > + ? __raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
>> > +
>> > + ? gic_enable_ppi(twd_irq);
>> > +}
>>
>> readl_relaxed()?
>>
> Ok. ?You get the best judgement on this.
>
You don't have to save local timer registers any more. The local timer
is always re-configued and this is already handled in common kernel.

You can drop above change and test your patches. I am sure they will
still work.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-06 19:14   ` Arnd Bergmann
@ 2011-09-07  6:05     ` Shawn Guo
  2011-09-07  7:56       ` Arnd Bergmann
  2011-09-07 12:43       ` Barry Song
  0 siblings, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  6:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Tue, Sep 06, 2011 at 09:14:29PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:37 Shawn Guo wrote:
> > It adds a number of core drivers support for imx6q, including clock,
> > General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
> > System Reset Controller (src).
> > 
> > Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> >  arch/arm/mach-imx/Kconfig       |   13 +
> >  arch/arm/mach-imx/Makefile      |    4 +
> >  arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
> >  arch/arm/mach-imx/gpc.c         |  110 +++
> >  arch/arm/mach-imx/mmdc.c        |   71 ++
> >  arch/arm/mach-imx/src.c         |   52 +
> >  6 files changed, 2240 insertions(+), 0 deletions(-)
> 
> This is unfortunately still a major problem.

It's so sad to still get this comment.  Back to Linaro Connect on
Cambridge, I believe I asked for your opinion on new SoC clock support
without waiting for the clock framework.  You said you do not have a
strong position on this and would defer to others' judgement.  Then
I talked to Russell and Grant respectively, and they both agree that
we should not be blocked by the clock framework.  That's why I decided
to start upstreaming imx6q.

> I realize that we don't
> yet have a good framework to do this with significantly less code,
> but adding a platform that is mostly consisting of stupid additions
> of clock descriptions that really should be in the device tree does
> not scale much longer.

I definitely agree this does not scale for long term.  And I would
immediately migrate it to clock framework once it gets ready and put
the description into device tree when clock binding is ready.  Before
we get there, we need a way out.  It's unreasonable for us to hold
the new soc support for an unspecified time.  It's been 20 months since
we saw the common clock patches[1] from Jeremy, and we do not know yet
how many months we still have to wait.  Grant worked out the auxdata to
remove the device tree dependency on clock framework.  I think we
should not get new soc support blocked by clock framework either.

> We decided to let this still get in for prima2,
> which was also ugly in this regard but much simpler than imx6.
> 
It's unfair to me that you reject imx6q clock code just because it's
an implementation for a hardware complexer than prima2.

> My feeling is that this time, we should wait for the common clock
> framework to get in and simplify this. I believe Thomas is now planning
> to do this, but I haven't followed what the current state is.
> 
Sadly, if this is the position of entire arm-soc maintainer group,
I think I have made a wrong decision to start upstreaming imx6q now.

> The other three drivers in this patch are basically ok, so you can
> definitely post them as a separate patch and perhaps get minor comments
> for those, similar to what I commented on the other patches.
> 
> For the clock-imx6q.c file, what I first want to hear from someone
> is how this is supposed to look like in the long run with device tree
> integration, and how far away from that we are.
> 
> Can you comment on how far we get without the clock driver with imx6?
> Is is basically useless, or is there a way we can merge the remaining
> imx6 code and other drivers but postpone the large clock driver?
> 
Unfortunately, clock is pretty fundamental for imx6q support.  Without
clock support, imx6q platform is useless.  We have a real example here.
Back to Dec. 2010, Sascha refused to take clock patch when Freescale
was submitting imx50 platform support, because he thought the clock
framework will get merged pretty soon.  But we end up with the facts
that clock framework is still up in the air and imx50 platform support
on mainline is totally useless.

I have been tried very hard to reduce the LOC of clock-imx6q.c.  It's
a 5K LOC file in the Freescale internal tree.  Now it's 2K LOC.  I know
it's still large enough for you to dislike it.  But this is the clock
that the hardware has.  I'm afraid we can not do much to reduce the LOC
significantly, unless we only implement the small portion other than
the full clock tree, which is what I really hate to do.

Regards,
Shawn

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2010-January/007238.html

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

* [PATCH 5/6] arm/imx6q: add device tree machine support
  2011-09-07  3:07     ` Shawn Guo
@ 2011-09-07  7:26       ` Arnd Bergmann
  0 siblings, 0 replies; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-07  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 07 September 2011 11:07:34 Shawn Guo wrote:
> On Tue, Sep 06, 2011 at 08:55:45PM +0200, Arnd Bergmann wrote:
> > On Tuesday 06 September 2011 17:58:39 Shawn Guo wrote:
> > 
> > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > > index 13e0301..3364b59 100644
> > > --- a/arch/arm/mach-imx/Kconfig
> > > +++ b/arch/arm/mach-imx/Kconfig
> > > @@ -624,3 +624,16 @@ config MACH_VPR200
> > >       configurations for the board and its peripherals.
> > >  
> > >  endif
> > > +
> > > +if ARCH_MX6
> > > +comment "i.MX6 machines:"
> > > +
> > > +config MACH_IMX6Q
> > > +   bool "Support i.MX6 Quad platforms from device tree"
> > > +   select SOC_IMX6Q
> > > +   select USE_OF
> > > +   help
> > > +     Include support for Freescale i.MX6 Quad based platforms
> > > +     using the device tree for discovery
> > > +
> > > +endif
> > 
> > As we have done on zynq and prima2, I would suggest not to add multiple
> > machines types at all. You already have the intialization in a generic
> > imx6q file, it would be logical to get rid of the configuration entry
> > as well.
> > 
> This MACH_IMX6Q was added to make the IMX6Q Kconfig hierarchy look
> consistent with other SoCs in arch/arm/mach-imx/Kconfig.  If you
> do not like it, I can kill it.

Yes, plase do. I think we should in the long run get more platforms
to do the same, it will be a sign that mx6 is part of the new generation.

	Arnd

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

* [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support
  2011-09-07  5:08       ` Shilimkar, Santosh
@ 2011-09-07  7:46         ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 10:38:10AM +0530, Shilimkar, Santosh wrote:
> On Wed, Sep 7, 2011 at 10:11 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
> > On Tue, Sep 06, 2011 at 08:53:07PM +0200, Arnd Bergmann wrote:
> >> On Tuesday 06 September 2011 17:58:38 Shawn Guo wrote:
> >> > It adds smp and cpu hotplug support for imx6q.
> >> > +static u32 twd_saved_regs[4];
> >> > +static int twd_irq;
> >> > +
> >> > +/*
> >> > + * Resuming from ARM Dormant/Shutdown mode, the boot procedure will
> >> > + * re-setup local timer for secondary cores. ?For primary core, it
> >> > + * has to take care of itself with the following pair of functions
> >> > + * during suspend/resume.
> >> > + */
> >> > +void imx_local_timer_pre_suspend(void)
> >> > +{
> >> > + ? twd_saved_regs[0] = __raw_readl(twd_base + TWD_TIMER_LOAD);
> >> > + ? twd_saved_regs[1] = __raw_readl(twd_base + TWD_TIMER_COUNTER);
> >> > + ? twd_saved_regs[2] = __raw_readl(twd_base + TWD_TIMER_CONTROL);
> >> > + ? twd_saved_regs[3] = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
> >> > +}
> >> > +
> >> > +void imx_local_timer_post_resume(void)
> >> > +{
> >> > + ? __raw_writel(twd_saved_regs[0], twd_base + TWD_TIMER_LOAD);
> >> > + ? __raw_writel(twd_saved_regs[1], twd_base + TWD_TIMER_COUNTER);
> >> > + ? __raw_writel(twd_saved_regs[2], twd_base + TWD_TIMER_CONTROL);
> >> > + ? __raw_writel(twd_saved_regs[3], twd_base + TWD_TIMER_INTSTAT);
> >> > +
> >> > + ? gic_enable_ppi(twd_irq);
> >> > +}
> >>
> >> readl_relaxed()?
> >>
> > Ok. ?You get the best judgement on this.
> >
> You don't have to save local timer registers any more. The local timer
> is always re-configued and this is already handled in common kernel.
> 
> You can drop above change and test your patches. I am sure they will
> still work.
> 
Ah, yes.  This registers saving/restoring was added together with
cpu0 twd_irq enabling when I use git_reinit() approach, which turns
out to be unnecessary.  This pair of imx_local_timer_pre_suspend/resume
can totally be removed now, since "CPU PM notifiers" patches come to
play.

Thanks for catching this, Santosh.

-- 
Regards,
Shawn

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-07  6:05     ` Shawn Guo
@ 2011-09-07  7:56       ` Arnd Bergmann
  2011-09-12 16:12         ` Shawn Guo
  2011-09-07 12:43       ` Barry Song
  1 sibling, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-07  7:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:

> > >  arch/arm/mach-imx/Kconfig       |   13 +
> > >  arch/arm/mach-imx/Makefile      |    4 +
> > >  arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
> > >  arch/arm/mach-imx/gpc.c         |  110 +++
> > >  arch/arm/mach-imx/mmdc.c        |   71 ++
> > >  arch/arm/mach-imx/src.c         |   52 +
> > >  6 files changed, 2240 insertions(+), 0 deletions(-)
> > 
> > This is unfortunately still a major problem.
> 
> It's so sad to still get this comment.  Back to Linaro Connect on
> Cambridge, I believe I asked for your opinion on new SoC clock support
> without waiting for the clock framework.  You said you do not have a
> strong position on this and would defer to others' judgement.  Then
> I talked to Russell and Grant respectively, and they both agree that
> we should not be blocked by the clock framework.  That's why I decided
> to start upstreaming imx6q.

I don't mind being overruled on this if Russell, Grant or others have a good
feeling about the clock code going in like this.

I thought that the discussion we had in Cambridge was about migrating the
existing i.mx code to device tree without waiting for the clock framework.
If I misremember that and we had actually made a different decision back
then, then please forgive my overreaction.

> > I realize that we don't
> > yet have a good framework to do this with significantly less code,
> > but adding a platform that is mostly consisting of stupid additions
> > of clock descriptions that really should be in the device tree does
> > not scale much longer.
> 
> I definitely agree this does not scale for long term.  And I would
> immediately migrate it to clock framework once it gets ready and put
> the description into device tree when clock binding is ready.  Before
> we get there, we need a way out.  It's unreasonable for us to hold
> the new soc support for an unspecified time.  It's been 20 months since
> we saw the common clock patches[1] from Jeremy, and we do not know yet
> how many months we still have to wait.  Grant worked out the auxdata to
> remove the device tree dependency on clock framework.  I think we
> should not get new soc support blocked by clock framework either.
> 
> > We decided to let this still get in for prima2,
> > which was also ugly in this regard but much simpler than imx6.
> > 
> It's unfair to me that you reject imx6q clock code just because it's
> an implementation for a hardware complexer than prima2.

We have to stop taking new platform clock code at some point and get
all new platforms to use common code as much as possible. The unresolved
question here is when that will be. My feeling is that prima2 was
borderline and this is too far, but I may be pushing it here given
that we are still waiting for the clock framework to actually get
merged.

However, if there is no pressure at all, we might never see that framework.

> > My feeling is that this time, we should wait for the common clock
> > framework to get in and simplify this. I believe Thomas is now planning
> > to do this, but I haven't followed what the current state is.
> > 
> Sadly, if this is the position of entire arm-soc maintainer group,
> I think I have made a wrong decision to start upstreaming imx6q now.

We haven't discussed it as a group, it's my own opinion.

> > The other three drivers in this patch are basically ok, so you can
> > definitely post them as a separate patch and perhaps get minor comments
> > for those, similar to what I commented on the other patches.
> > 
> > For the clock-imx6q.c file, what I first want to hear from someone
> > is how this is supposed to look like in the long run with device tree
> > integration, and how far away from that we are.
> > 
> > Can you comment on how far we get without the clock driver with imx6?
> > Is is basically useless, or is there a way we can merge the remaining
> > imx6 code and other drivers but postpone the large clock driver?
> > 
> Unfortunately, clock is pretty fundamental for imx6q support.  Without
> clock support, imx6q platform is useless.  We have a real example here.
> Back to Dec. 2010, Sascha refused to take clock patch when Freescale
> was submitting imx50 platform support, because he thought the clock
> framework will get merged pretty soon.  But we end up with the facts
> that clock framework is still up in the air and imx50 platform support
> on mainline is totally useless.
> 
> I have been tried very hard to reduce the LOC of clock-imx6q.c.  It's
> a 5K LOC file in the Freescale internal tree.  Now it's 2K LOC.  I know
> it's still large enough for you to dislike it.  But this is the clock
> that the hardware has.  I'm afraid we can not do much to reduce the LOC
> significantly, unless we only implement the small portion other than
> the full clock tree, which is what I really hate to do.

I actually think that you have done a great job on the code and that it
certainly looks better than a lot of the other implementations that we
have in the tree.

Also, at least half of the code is now real driver code that we won't
be able to reduce any further even with the clock framework. However,
when I look at long sets of DEF_CLK and DEF_*MUX and _REGISTER_CLOCK,
it feels like exactly the stuff that we should be moving into the
device tree and have automatically parsed.

	Arnd

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06 18:39   ` Arnd Bergmann
@ 2011-09-07  8:50     ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07  8:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 08:39:29PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:36 Shawn Guo wrote:
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > @@ -0,0 +1,29 @@
> > +#ifndef __MACH_MX6Q_H__
> > +#define __MACH_MX6Q_H__
> > +
> > +/* static mappings */
> > +#define IMX6Q_VA(x)            (0xf4000000 + (x))
> 
> This should return a 'void __iomem *' pointer, not an integer.
> 
To pair the virtual address and physical address which is an integer,
I chose to define the virtual address as integer too, and cast it to
pointer when using it using helper macro IOMEM() defined in
arch/arm/plat-mxc/include/mach/hardware.h.

> > +#define MX6Q_SCU_BASE_ADDR     0x00a00000
> > +#define MX6Q_CCM_BASE_ADDR     0x020c4000
> > +#define MX6Q_ANATOP_BASE_ADDR  0x020c8000
> > +#define MX6Q_UART4_BASE_ADDR   0x021f0000
> > +
> > +#define MX6Q_SCU_BASE_VADDR    IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > +#define MX6Q_CCM_BASE_VADDR    IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > +#define MX6Q_ANATOP_BASE_VADDR IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > +#define MX6Q_UART4_BASE_VADDR  IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> 
> The list is reasonably short, but I think you can still try harder to remove
> some of the remaining elements. I can understand the need for UART4
> (for ll_debug), but I don't really understand what the others are and
> why you cannot get the values from the device tree and ioremap them.
> 
For SCU_BASE, the definition is actually unused, since physical base
of SCU can be retrieved from coprocessor.  I put them here for
documentation purpose telling it's a static mapping.

For CCM and ANATOP, the static mappings are used by clock code, because
"struct clk" is statically defined and initialized.  They can become
dynamic mapping when we migrate the clock to common framework and
device tree.

> Maybe you can add a few comments to explain these if they are indeed
> necessary.
> 
Ok, will do.

-- 
Regards,
Shawn

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

* [PATCH 0/6] add initial imx6q support
  2011-09-07  2:55     ` Shawn Guo
@ 2011-09-07  9:39       ` Arnd Bergmann
  0 siblings, 0 replies; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-07  9:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 07 September 2011 10:55:12 Shawn Guo wrote:
> On Tue, Sep 06, 2011 at 09:42:53PM +0200, Uwe Kleine-K?nig wrote:
> > Hello Arnd,
> > 
> > On Tue, Sep 06, 2011 at 08:28:39PM +0200, Arnd Bergmann wrote:
> > > We've talked about it before, but I don't remember the outcome. Can you
> > > explain (and add to the above text) a short explanation of why this is
> > > in the mach-imx directory, rather than the mach-mx5 (which probably is
> > > closer to mx6 than mx3 is) or a new mach-mx6?
> > Not having looked into the patches yet, but I think mach-imx is the
> > right choice. The longterm plan for mach-mx5 is to be folded into
> > mach-imx, too. We just didn't found a volunteer for that.
> 
> My plan is to convert all the board files in mach-mx5 to imx51-dt.c
> and imx53-dt.c first, and then merge the folder into mach-imx.

Ok, sounds good.

Thanks,
	
	Arnd

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06 20:25   ` Uwe Kleine-König
@ 2011-09-07 11:00     ` Shawn Guo
  2011-09-07 12:36       ` Uwe Kleine-König
  2011-09-12  8:44       ` Sascha Hauer
  2011-09-15  1:24     ` Shawn Guo
  1 sibling, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> > It adds the core definitions and low-level debug uart support
> > for imx6q.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> >  arch/arm/Kconfig                             |    2 +-
> >  arch/arm/Kconfig.debug                       |    7 +++++
> >  arch/arm/Makefile                            |    1 +
> >  arch/arm/mach-imx/Kconfig                    |    4 +++
> >  arch/arm/mach-imx/Makefile                   |    2 +
> >  arch/arm/mach-imx/Makefile.boot              |    4 +++
> >  arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
> >  arch/arm/plat-mxc/Kconfig                    |    5 ++++
> >  arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
> >  arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
> >  arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
> >  arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
> >  arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
> >  arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
> >  14 files changed, 115 insertions(+), 5 deletions(-)
> >  create mode 100644 arch/arm/mach-imx/lluart.c
> >  create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h
> > 
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 4ea9974..37c20a4 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -1348,7 +1348,7 @@ config SMP
> >  	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
> >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
> >  		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
> > -		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
> > +		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
> >  	select USE_GENERIC_SMP_HELPERS
> >  	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
> >  	help
> > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > index 965d59a..68fc155 100644
> > --- a/arch/arm/Kconfig.debug
> > +++ b/arch/arm/Kconfig.debug
> > @@ -155,6 +155,13 @@ choice
> >  		  Say Y here if you want kernel low-level debugging support
> >  		  on i.MX50 or i.MX53.
> >  
> > +	config DEBUG_IMX6Q_UART
> > +		bool "i.MX6Q Debug UART"
> > +		depends on SOC_IMX6Q
> > +		help
> > +		  Say Y here if you want kernel low-level debugging support
> > +		  on i.MX6Q.
> > +
> >  	config DEBUG_S3C_UART0
> >  		depends on PLAT_SAMSUNG
> >  		bool "Use S3C UART 0 for low-level debug"
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index 70c424e..3a0bbe4 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
> >  machine-$(CONFIG_ARCH_MX25)		:= imx
> >  machine-$(CONFIG_ARCH_MX3)		:= imx
> >  machine-$(CONFIG_ARCH_MX5)		:= mx5
> > +machine-$(CONFIG_ARCH_MX6)		:= imx
> >  machine-$(CONFIG_ARCH_MXS)		:= mxs
> >  machine-$(CONFIG_ARCH_NETX)		:= netx
> >  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
> > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > index 0519dd7..4cf5178 100644
> > --- a/arch/arm/mach-imx/Kconfig
> > +++ b/arch/arm/mach-imx/Kconfig
> > @@ -58,6 +58,10 @@ config SOC_IMX35
> >  	select ARCH_MX35
> >  	select MXC_AVIC
> >  
> > +config SOC_IMX6Q
> > +	bool
> > +	select ARM_GIC
> > +	select CPU_V7
> >  
> >  if ARCH_MX1
> >  
> > diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> > index e9eb36d..96ecc96 100644
> > --- a/arch/arm/mach-imx/Makefile
> > +++ b/arch/arm/mach-imx/Makefile
> > @@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
> >  obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
> >  obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
> >  obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> > +
> > +obj-$(CONFIG_DEBUG_LL) += lluart.o
> > diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> > index ebee18b..389a0e3 100644
> > --- a/arch/arm/mach-imx/Makefile.boot
> > +++ b/arch/arm/mach-imx/Makefile.boot
> > @@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
> >  zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
> >  params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
> >  initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
> > +
> > +zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
> > +params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
> > +initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
> Do you really need params_phys and initrd_phys?
> 
I added them to make IMX6Q look consistent with other soc in the file,
and leave it to a global cleanup, if we decide to clean later.

> > diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
> > new file mode 100644
> > index 0000000..34205cb
> > --- /dev/null
> > +++ b/arch/arm/mach-imx/lluart.c
> > @@ -0,0 +1,33 @@
> > +/*
> > + * Copyright 2011 Freescale Semiconductor, Inc.
> > + * Copyright 2011 Linaro Ltd.
> > + *
> > + * 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 <linux/init.h>
> > +#include <asm/page.h>
> > +#include <asm/sizes.h>
> > +#include <asm/mach/map.h>
> > +#include <mach/hardware.h>
> > +
> > +static struct map_desc imx_lluart_desc = {
> > +#ifdef CONFIG_DEBUG_IMX6Q_UART
> > +	.virtual	= MX6Q_UART4_BASE_VADDR,
> > +	.pfn		= __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
> > +	.length		= SZ_16K,
> > +	.type		= MT_DEVICE,
> > +#endif
> > +};
> > +
> > +void __init imx_lluart_map_io(void)
> > +{
> > +	if (imx_lluart_desc.virtual)
> > +		iotable_init(&imx_lluart_desc, 1);
> > +}
> I don't see yet where this is called, but I wonder what happens on a
> non-imx6q machine (provided it is called there).

This is called by imx6q_map_io() in mach-imx6q.c.  For non-imx6q
machines, imx_lluart_desc will be all zero, therefore iotable_init()
call will be bypassed.

> > +
> > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> > index a5353fc..e548f9b 100644
> > --- a/arch/arm/plat-mxc/Kconfig
> > +++ b/arch/arm/plat-mxc/Kconfig
> > @@ -48,6 +48,11 @@ config ARCH_MX51
> >  	help
> >  	  This enables support for systems based on the Freescale i.MX51 family
> >  
> > +config ARCH_MX6
> > +	bool "i.MX6"
> > +	help
> > +	  This enables support for systems based on the Freescale i.MX6 family
> > +
> >  endchoice
> >  
> >  source "arch/arm/mach-imx/Kconfig"
> > diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > index 07cfdbe..471872a 100644
> > --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> > +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > @@ -24,9 +24,14 @@
> >  #define UART_PADDR	MX51_UART1_BASE_ADDR
> >  #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
> >  #define UART_PADDR	MX53_UART1_BASE_ADDR
> > +#elif defined (CONFIG_DEBUG_IMX6Q_UART)
> > +#define UART_PADDR	MX6Q_UART4_BASE_ADDR
> > +#define UART_VADDR	MX6Q_UART4_BASE_VADDR
> You cannot use the existing IMX_IO_P2V? I'd like to have a look into it
> to make it usable there, too. See below.
> 
> >  #endif
> >  
> > +#ifndef UART_VADDR
> >  #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
> > +#endif
> >  
> >  		.macro	addruart, rp, rv
> >  		ldr	\rp, =UART_PADDR	@ physical
> > diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > index 066d464..341f800 100644
> > --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> > +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > @@ -1,6 +1,6 @@
> >  /*
> >   *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> > - *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> > + *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
> >   */
> >  
> >  /*
> > @@ -11,6 +11,17 @@
> >  
> >  #include <mach/hardware.h>
> >  
> > +#ifdef CONFIG_ARM_GIC
> > +#include <asm/hardware/entry-macro-gic.S>
> > +
> > +	.macro	disable_fiq
> > +	.endm
> > +
> > +	.macro	arch_ret_to_user, tmp1, tmp2
> > +	.endm
> > +
> > +#else
> > +
> hmm, this essentially means mx6 support cannot go into a kernel image
> for the other imx machines :-(
> 
Ah, sorry.  I totally forgot about this.  Will fix it in the next
version.

> >  #define AVIC_NIMASK	0x04
> >  
> >  	@ this macro disables fast irq (not implemented)
> > @@ -78,3 +89,5 @@
> >  	movs \irqnr, \irqnr
> >  #endif
> >  	.endm
> > +
> > +#endif /* CONFIG_ARM_GIC */
> > diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> > index a8bfd56..e1f84ce 100644
> > --- a/arch/arm/plat-mxc/include/mach/hardware.h
> > +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> > @@ -97,6 +97,7 @@
> >  
> >  #include <mach/mxc.h>
> >  
> > +#include <mach/mx6q.h>
> >  #include <mach/mx50.h>
> >  #include <mach/mx51.h>
> >  #include <mach/mx53.h>
> > diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> > index 00e812b..3ae400f 100644
> > --- a/arch/arm/plat-mxc/include/mach/irqs.h
> > +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> > @@ -14,12 +14,15 @@
> >  #include <asm-generic/gpio.h>
> >  
> >  /*
> > - * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> > + * SoCs with AVIC interrupt controller have 64 IRQs, those with TZIC
> > + * have 128, otherwise those with GIC have 160 IRQs.
> >   */
> > -#ifdef CONFIG_MXC_TZIC
> > +#if defined CONFIG_MXC_AVIC
> > +#define MXC_INTERNAL_IRQS	64
> > +#elif defined CONFIG_MXC_TZIC
> >  #define MXC_INTERNAL_IRQS	128
> >  #else
> > -#define MXC_INTERNAL_IRQS	64
> > +#define MXC_INTERNAL_IRQS	160
> >  #endif
> This is broken. The highest number has to go to the top. Otherwise if
> you have an image with at least 2 of the available irq controllers your
> MXC_INTERNAL_IRQS is too small.
> 
Yes, this is yet another one I forgot about single image support.
I should probably put some documentation about the correct order,
which can be forgot by people like me.

Thanks for catching this.

> >  
> >  #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
> > diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> > index 11be5cd..2b8e186 100644
> > --- a/arch/arm/plat-mxc/include/mach/memory.h
> > +++ b/arch/arm/plat-mxc/include/mach/memory.h
> > @@ -19,6 +19,7 @@
> >  #define MX50_PHYS_OFFSET	UL(0x70000000)
> >  #define MX51_PHYS_OFFSET	UL(0x90000000)
> >  #define MX53_PHYS_OFFSET	UL(0x70000000)
> > +#define MX6Q_PHYS_OFFSET	UL(0x10000000)
> >  
> >  #if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
> >  # if defined CONFIG_ARCH_MX1
> > @@ -37,6 +38,8 @@
> >  #  define PLAT_PHYS_OFFSET		MX51_PHYS_OFFSET
> >  # elif defined CONFIG_ARCH_MX53
> >  #  define PLAT_PHYS_OFFSET		MX53_PHYS_OFFSET
> > +# elif defined CONFIG_SOC_IMX6Q
> > +#  define PLAT_PHYS_OFFSET		MX6Q_PHYS_OFFSET
> >  # endif
> >  #endif
> >  
> > diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> > new file mode 100644
> > index 0000000..7432310
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > @@ -0,0 +1,29 @@
> > +/*
> > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > + * Copyright 2011 Linaro Ltd.
> > + *
> > + * 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
> > + */
> > +
> > +#ifndef __MACH_MX6Q_H__
> > +#define __MACH_MX6Q_H__
> > +
> > +/* static mappings */
> > +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> > +
> > +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> > +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> > +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> > +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> > +
> > +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> Depending on the sizes of these memory regions you can use the existing
> IMX_IO_P2V here. The conditions are:
> 
> 	SCU_SIZE <= 0x200000
> 	CCM_SIZE <= 0x4000
> 	ANATOP_SIZE <= 0x28000
> 	UART4 <= 0x100000
> 
This is exactly what I dislike about IMX_IO_P2V().  We have to verify
all these conditions manually.  Looking at the static mapping below
(copied from arch/arm/plat-mxc/include/mach/hardware.h), do you think
it's really scalable and easy to maintain for the long run?

/*
 * This is rather complicated for humans and ugly to verify, but for a machine
 * it's OK.  Still more as it is usually only applied to constants.  The upsides
 * on using this approach are:
 *
 *  - same mapping on all i.MX machines
 *  - works for assembler, too
 *  - no need to nurture #defines for virtual addresses
 *
 * The downside it, it's hard to verify (but I have a script for that).
 *
 * Obviously this needs to be injective for each SoC.  In general it maps the
 * whole address space to [0xf4000000, 0xf5ffffff].  So [0xf6000000,0xfeffffff]
 * is free for per-machine use (e.g. KZM_ARM11_01 uses 64MiB there).
 *
 * It applies the following mappings for the different SoCs:
 *
 * mx1:
 *	IO	0x00200000+0x100000	->	0xf4000000+0x100000
 * mx21:
 *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
 *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
 *	X_MEMC	0xdf000000+0x004000	->	0xf5f00000+0x004000
 * mx25:
 *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
 *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
 *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
 * mx27:
 *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
 *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
 *	X_MEMC	0xd8000000+0x100000	->	0xf5c00000+0x100000
 * mx31:
 *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
 *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
 *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
 *	X_MEMC	0xb8000000+0x010000	->	0xf4c00000+0x010000
 *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
 * mx35:
 *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
 *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
 *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
 *	X_MEMC	0xb8000000+0x010000	->	0xf4c00000+0x010000
 *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
 * mx50:
 *	TZIC	0x0fffc000+0x004000	->	0xf4bfc000+0x004000
 *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
 *	AIPS1	0x53f00000+0x100000	->	0xf5700000+0x100000
 *	AIPS2	0x63f00000+0x100000	->	0xf5300000+0x100000
 * mx51:
 *	IRAM	0x1ffe0000+0x020000	->	0xf4fe0000+0x020000
 *	DEBUG	0x60000000+0x100000	->	0xf5000000+0x100000
 *	SPBA0	0x70000000+0x100000	->	0xf5400000+0x100000
 *	AIPS1	0x73f00000+0x100000	->	0xf5700000+0x100000
 *	AIPS2	0x83f00000+0x100000	->	0xf4300000+0x100000
 */
#define IMX_IO_P2V(x)	(						\
			0xf4000000 +					\
			(((x) & 0x50000000) >> 6) +			\
			(((x) & 0x0b000000) >> 4) +			\
			(((x) & 0x000fffff)))

> hmm, looking at patch 4 SCU_BASE is determined by a coprocessor
> instruction?!

Ah, yes.  The SCU physical base address can be retrieved from
coprocessor.

Regards,
Shawn

> Other than that these restrictions seem to be fulfilled.
> 

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

* [PATCH 1/6] arm/imx6q: add device tree source
  2011-09-06 18:31   ` Arnd Bergmann
@ 2011-09-07 11:16     ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-07 11:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 08:31:47PM +0200, Arnd Bergmann wrote:
> On Tuesday 06 September 2011 17:58:35 Shawn Guo wrote:
> > +
> > +       aips-bus at 02000000 { /* AIPS1 */
> > +               compatible = "fsl,aips-bus", "simple-bus";
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               reg = <0x02000000 0x100000>;
> > +               ranges;
> > +
> > +               spba-bus at 02000000 {
> > +                       compatible = "fsl,spba-bus", "simple-bus";
> > +                       #address-cells = <1>;
> > +                       #size-cells = <1>;
> > +                       reg = <0x02000000 0x40000>;
> > +                       ranges;
> 
> Wouldn't it be better to have the ranges property translate bus-local addresses
> to global addresses, rather than having an empty ranges property?
> 
All the bus-local addresses are directly mapped into cpu address
space.  Looking at the i.MX Reference Manual memory map chapter,
the base address of each block is given in global address other than
bus address + offset.  Writing a global address in device tree is
relatively easy to match the addresses defined in hardware document.

-- 
Regards,
Shawn

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 11:00     ` Shawn Guo
@ 2011-09-07 12:36       ` Uwe Kleine-König
  2011-09-07 14:23         ` Russell King - ARM Linux
  2011-09-12  2:30         ` Shawn Guo
  2011-09-12  8:44       ` Sascha Hauer
  1 sibling, 2 replies; 69+ messages in thread
From: Uwe Kleine-König @ 2011-09-07 12:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> > > It adds the core definitions and low-level debug uart support
> > > for imx6q.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > > ---
> > >  arch/arm/Kconfig                             |    2 +-
> > >  arch/arm/Kconfig.debug                       |    7 +++++
> > >  arch/arm/Makefile                            |    1 +
> > >  arch/arm/mach-imx/Kconfig                    |    4 +++
> > >  arch/arm/mach-imx/Makefile                   |    2 +
> > >  arch/arm/mach-imx/Makefile.boot              |    4 +++
> > >  arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
> > >  arch/arm/plat-mxc/Kconfig                    |    5 ++++
> > >  arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
> > >  arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
> > >  arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
> > >  arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
> > >  arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
> > >  arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
> > >  14 files changed, 115 insertions(+), 5 deletions(-)
> > >  create mode 100644 arch/arm/mach-imx/lluart.c
> > >  create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h
> > > 
> > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > > index 4ea9974..37c20a4 100644
> > > --- a/arch/arm/Kconfig
> > > +++ b/arch/arm/Kconfig
> > > @@ -1348,7 +1348,7 @@ config SMP
> > >  	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
> > >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
> > >  		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
> > > -		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
> > > +		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
> > >  	select USE_GENERIC_SMP_HELPERS
> > >  	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
> > >  	help
> > > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > > index 965d59a..68fc155 100644
> > > --- a/arch/arm/Kconfig.debug
> > > +++ b/arch/arm/Kconfig.debug
> > > @@ -155,6 +155,13 @@ choice
> > >  		  Say Y here if you want kernel low-level debugging support
> > >  		  on i.MX50 or i.MX53.
> > >  
> > > +	config DEBUG_IMX6Q_UART
> > > +		bool "i.MX6Q Debug UART"
> > > +		depends on SOC_IMX6Q
> > > +		help
> > > +		  Say Y here if you want kernel low-level debugging support
> > > +		  on i.MX6Q.
> > > +
> > >  	config DEBUG_S3C_UART0
> > >  		depends on PLAT_SAMSUNG
> > >  		bool "Use S3C UART 0 for low-level debug"
> > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > index 70c424e..3a0bbe4 100644
> > > --- a/arch/arm/Makefile
> > > +++ b/arch/arm/Makefile
> > > @@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
> > >  machine-$(CONFIG_ARCH_MX25)		:= imx
> > >  machine-$(CONFIG_ARCH_MX3)		:= imx
> > >  machine-$(CONFIG_ARCH_MX5)		:= mx5
> > > +machine-$(CONFIG_ARCH_MX6)		:= imx
> > >  machine-$(CONFIG_ARCH_MXS)		:= mxs
> > >  machine-$(CONFIG_ARCH_NETX)		:= netx
> > >  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
> > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > > index 0519dd7..4cf5178 100644
> > > --- a/arch/arm/mach-imx/Kconfig
> > > +++ b/arch/arm/mach-imx/Kconfig
> > > @@ -58,6 +58,10 @@ config SOC_IMX35
> > >  	select ARCH_MX35
> > >  	select MXC_AVIC
> > >  
> > > +config SOC_IMX6Q
> > > +	bool
> > > +	select ARM_GIC
> > > +	select CPU_V7
> > >  
> > >  if ARCH_MX1
> > >  
> > > diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> > > index e9eb36d..96ecc96 100644
> > > --- a/arch/arm/mach-imx/Makefile
> > > +++ b/arch/arm/mach-imx/Makefile
> > > @@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
> > >  obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
> > >  obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
> > >  obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> > > +
> > > +obj-$(CONFIG_DEBUG_LL) += lluart.o
> > > diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> > > index ebee18b..389a0e3 100644
> > > --- a/arch/arm/mach-imx/Makefile.boot
> > > +++ b/arch/arm/mach-imx/Makefile.boot
> > > @@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
> > >  zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
> > >  params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
> > >  initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
> > > +
> > > +zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
> > > +params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
> > > +initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
> > Do you really need params_phys and initrd_phys?
> > 
> I added them to make IMX6Q look consistent with other soc in the file,
> and leave it to a global cleanup, if we decide to clean later.
If you ask me don't do that. Better do it for imx6q as clean as
possible.

> > > diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
> > > new file mode 100644
> > > index 0000000..34205cb
> > > --- /dev/null
> > > +++ b/arch/arm/mach-imx/lluart.c
> > > @@ -0,0 +1,33 @@
> > > +/*
> > > + * Copyright 2011 Freescale Semiconductor, Inc.
> > > + * Copyright 2011 Linaro Ltd.
> > > + *
> > > + * 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 <linux/init.h>
> > > +#include <asm/page.h>
> > > +#include <asm/sizes.h>
> > > +#include <asm/mach/map.h>
> > > +#include <mach/hardware.h>
> > > +
> > > +static struct map_desc imx_lluart_desc = {
> > > +#ifdef CONFIG_DEBUG_IMX6Q_UART
> > > +	.virtual	= MX6Q_UART4_BASE_VADDR,
> > > +	.pfn		= __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
> > > +	.length		= SZ_16K,
> > > +	.type		= MT_DEVICE,
> > > +#endif
> > > +};
> > > +
> > > +void __init imx_lluart_map_io(void)
> > > +{
> > > +	if (imx_lluart_desc.virtual)
> > > +		iotable_init(&imx_lluart_desc, 1);
> > > +}
> > I don't see yet where this is called, but I wonder what happens on a
> > non-imx6q machine (provided it is called there).
> 
> This is called by imx6q_map_io() in mach-imx6q.c.  For non-imx6q
> machines, imx_lluart_desc will be all zero,
But only if the image doesn't support imx6q, right? Anyhow, I hope
imx6q_map_io isn't called for pre-imx6q SoCs. Ah, and I hope we don't
need to argue here as Russell doesn't like the new DEBUG_LL changes :-)


>                                             therefore iotable_init()
> call will be bypassed.

> 
> > > +
> > > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> > > index a5353fc..e548f9b 100644
> > > --- a/arch/arm/plat-mxc/Kconfig
> > > +++ b/arch/arm/plat-mxc/Kconfig
> > > @@ -48,6 +48,11 @@ config ARCH_MX51
> > >  	help
> > >  	  This enables support for systems based on the Freescale i.MX51 family
> > >  
> > > +config ARCH_MX6
> > > +	bool "i.MX6"
> > > +	help
> > > +	  This enables support for systems based on the Freescale i.MX6 family
> > > +
> > >  endchoice
> > >  
> > >  source "arch/arm/mach-imx/Kconfig"
> > > diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > > index 07cfdbe..471872a 100644
> > > --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> > > +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > > @@ -24,9 +24,14 @@
> > >  #define UART_PADDR	MX51_UART1_BASE_ADDR
> > >  #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
> > >  #define UART_PADDR	MX53_UART1_BASE_ADDR
> > > +#elif defined (CONFIG_DEBUG_IMX6Q_UART)
> > > +#define UART_PADDR	MX6Q_UART4_BASE_ADDR
> > > +#define UART_VADDR	MX6Q_UART4_BASE_VADDR
> > You cannot use the existing IMX_IO_P2V? I'd like to have a look into it
> > to make it usable there, too. See below.
> > 
> > >  #endif
> > >  
> > > +#ifndef UART_VADDR
> > >  #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
> > > +#endif
> > >  
> > >  		.macro	addruart, rp, rv
> > >  		ldr	\rp, =UART_PADDR	@ physical
> > > diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > > index 066d464..341f800 100644
> > > --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> > > +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > > @@ -1,6 +1,6 @@
> > >  /*
> > >   *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> > > - *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> > > + *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > >   */
> > >  
> > >  /*
> > > @@ -11,6 +11,17 @@
> > >  
> > >  #include <mach/hardware.h>
> > >  
> > > +#ifdef CONFIG_ARM_GIC
> > > +#include <asm/hardware/entry-macro-gic.S>
> > > +
> > > +	.macro	disable_fiq
> > > +	.endm
> > > +
> > > +	.macro	arch_ret_to_user, tmp1, tmp2
> > > +	.endm
> > > +
> > > +#else
> > > +
> > hmm, this essentially means mx6 support cannot go into a kernel image
> > for the other imx machines :-(
> > 
> Ah, sorry.  I totally forgot about this.  Will fix it in the next
> version.
> 
> > >  #define AVIC_NIMASK	0x04
> > >  
> > >  	@ this macro disables fast irq (not implemented)
> > > @@ -78,3 +89,5 @@
> > >  	movs \irqnr, \irqnr
> > >  #endif
> > >  	.endm
> > > +
> > > +#endif /* CONFIG_ARM_GIC */
> > > diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> > > index a8bfd56..e1f84ce 100644
> > > --- a/arch/arm/plat-mxc/include/mach/hardware.h
> > > +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> > > @@ -97,6 +97,7 @@
> > >  
> > >  #include <mach/mxc.h>
> > >  
> > > +#include <mach/mx6q.h>
> > >  #include <mach/mx50.h>
> > >  #include <mach/mx51.h>
> > >  #include <mach/mx53.h>
> > > diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> > > index 00e812b..3ae400f 100644
> > > --- a/arch/arm/plat-mxc/include/mach/irqs.h
> > > +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> > > @@ -14,12 +14,15 @@
> > >  #include <asm-generic/gpio.h>
> > >  
> > >  /*
> > > - * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> > > + * SoCs with AVIC interrupt controller have 64 IRQs, those with TZIC
> > > + * have 128, otherwise those with GIC have 160 IRQs.
> > >   */
> > > -#ifdef CONFIG_MXC_TZIC
> > > +#if defined CONFIG_MXC_AVIC
> > > +#define MXC_INTERNAL_IRQS	64
> > > +#elif defined CONFIG_MXC_TZIC
> > >  #define MXC_INTERNAL_IRQS	128
> > >  #else
> > > -#define MXC_INTERNAL_IRQS	64
> > > +#define MXC_INTERNAL_IRQS	160
> > >  #endif
> > This is broken. The highest number has to go to the top. Otherwise if
> > you have an image with at least 2 of the available irq controllers your
> > MXC_INTERNAL_IRQS is too small.
> > 
> Yes, this is yet another one I forgot about single image support.
> I should probably put some documentation about the correct order,
> which can be forgot by people like me.
Maybe just introduce a corresponding comment when you touch this part of
code anyhow?!

> > >  #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
> > > diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> > > index 11be5cd..2b8e186 100644
> > > --- a/arch/arm/plat-mxc/include/mach/memory.h
> > > +++ b/arch/arm/plat-mxc/include/mach/memory.h
> > > @@ -19,6 +19,7 @@
> > >  #define MX50_PHYS_OFFSET	UL(0x70000000)
> > >  #define MX51_PHYS_OFFSET	UL(0x90000000)
> > >  #define MX53_PHYS_OFFSET	UL(0x70000000)
> > > +#define MX6Q_PHYS_OFFSET	UL(0x10000000)
> > >  
> > >  #if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
> > >  # if defined CONFIG_ARCH_MX1
> > > @@ -37,6 +38,8 @@
> > >  #  define PLAT_PHYS_OFFSET		MX51_PHYS_OFFSET
> > >  # elif defined CONFIG_ARCH_MX53
> > >  #  define PLAT_PHYS_OFFSET		MX53_PHYS_OFFSET
> > > +# elif defined CONFIG_SOC_IMX6Q
> > > +#  define PLAT_PHYS_OFFSET		MX6Q_PHYS_OFFSET
> > >  # endif
> > >  #endif
> > >  
> > > diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > new file mode 100644
> > > index 0000000..7432310
> > > --- /dev/null
> > > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > @@ -0,0 +1,29 @@
> > > +/*
> > > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > > + * Copyright 2011 Linaro Ltd.
> > > + *
> > > + * 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
> > > + */
> > > +
> > > +#ifndef __MACH_MX6Q_H__
> > > +#define __MACH_MX6Q_H__
> > > +
> > > +/* static mappings */
> > > +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> > > +
> > > +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> > > +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> > > +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> > > +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> > > +
> > > +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > > +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > > +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > > +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> > Depending on the sizes of these memory regions you can use the existing
> > IMX_IO_P2V here. The conditions are:
> > 
> > 	SCU_SIZE <= 0x200000
Actually this should be 0x100000 as this is the size that is mapped in a
continous chunk.

> > 	CCM_SIZE <= 0x4000
> > 	ANATOP_SIZE <= 0x28000
> > 	UART4 <= 0x100000
> > 
> This is exactly what I dislike about IMX_IO_P2V().  We have to verify
> all these conditions manually.  Looking at the static mapping below
I did it semi-manual, I just put your constants for imx6q into my script
(all with size=0x4000 for now) and it told me:

...
 * mx6q:
 *	SCU	0x00a00000+0x004000	->	0xf4000000+0x004000
 *	CCM	0x020c4000+0x004000	->	0xf42c4000+0x004000
 *	ANATOP	0x020c8000+0x004000	->	0xf42c8000+0x004000
 *	UART4	0x021f0000+0x004000	->	0xf42f0000+0x004000
...

> (copied from arch/arm/plat-mxc/include/mach/hardware.h), do you think
> it's really scalable and easy to maintain for the long run?
At least it provides a way to verify the correctness of the mapping.
Before I introduced the mapping function there was a conflict IIRC.

> /*
>  * This is rather complicated for humans and ugly to verify, but for a machine
>  * it's OK.  Still more as it is usually only applied to constants.  The upsides
>  * on using this approach are:
>  *
>  *  - same mapping on all i.MX machines
>  *  - works for assembler, too
>  *  - no need to nurture #defines for virtual addresses
>  *
>  * The downside it, it's hard to verify (but I have a script for that).
If you want I can provide you that script.

>  * Obviously this needs to be injective for each SoC.  In general it maps the
>  * whole address space to [0xf4000000, 0xf5ffffff].  So [0xf6000000,0xfeffffff]
>  * is free for per-machine use (e.g. KZM_ARM11_01 uses 64MiB there).
>  *
>  * It applies the following mappings for the different SoCs:
>  *
>  * mx1:
>  *	IO	0x00200000+0x100000	->	0xf4000000+0x100000
>  * mx21:
>  *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
>  *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
>  *	X_MEMC	0xdf000000+0x004000	->	0xf5f00000+0x004000
>  * mx25:
>  *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
>  *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
>  *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
>  * mx27:
>  *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
>  *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
>  *	X_MEMC	0xd8000000+0x100000	->	0xf5c00000+0x100000
>  * mx31:
>  *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
>  *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
>  *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
>  *	X_MEMC	0xb8000000+0x010000	->	0xf4c00000+0x010000
>  *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
>  * mx35:
>  *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
>  *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
>  *	AVIC	0x68000000+0x100000	->	0xf5800000+0x100000
>  *	X_MEMC	0xb8000000+0x010000	->	0xf4c00000+0x010000
>  *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
>  * mx50:
>  *	TZIC	0x0fffc000+0x004000	->	0xf4bfc000+0x004000
>  *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
>  *	AIPS1	0x53f00000+0x100000	->	0xf5700000+0x100000
>  *	AIPS2	0x63f00000+0x100000	->	0xf5300000+0x100000
>  * mx51:
>  *	IRAM	0x1ffe0000+0x020000	->	0xf4fe0000+0x020000
>  *	DEBUG	0x60000000+0x100000	->	0xf5000000+0x100000
>  *	SPBA0	0x70000000+0x100000	->	0xf5400000+0x100000
>  *	AIPS1	0x73f00000+0x100000	->	0xf5700000+0x100000
>  *	AIPS2	0x83f00000+0x100000	->	0xf4300000+0x100000
>  */
> #define IMX_IO_P2V(x)	(						\
> 			0xf4000000 +					\
> 			(((x) & 0x50000000) >> 6) +			\
> 			(((x) & 0x0b000000) >> 4) +			\
> 			(((x) & 0x000fffff)))
> 
> > hmm, looking at patch 4 SCU_BASE is determined by a coprocessor
> > instruction?!
> 
> Ah, yes.  The SCU physical base address can be retrieved from
> coprocessor.
Is there an advantage in autodetecting the base address?
 
Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-07  6:05     ` Shawn Guo
  2011-09-07  7:56       ` Arnd Bergmann
@ 2011-09-07 12:43       ` Barry Song
  2011-09-08  6:48         ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Barry Song @ 2011-09-07 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

2011/9/7 Shawn Guo <shawn.guo@freescale.com>:
> Hi Arnd,
>
> On Tue, Sep 06, 2011 at 09:14:29PM +0200, Arnd Bergmann wrote:
>> On Tuesday 06 September 2011 17:58:37 Shawn Guo wrote:
>> > It adds a number of core drivers support for imx6q, including clock,
>> > General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
>> > System Reset Controller (src).
>> >
>> > Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
>> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>> > ---
>> > ?arch/arm/mach-imx/Kconfig ? ? ? | ? 13 +
>> > ?arch/arm/mach-imx/Makefile ? ? ?| ? ?4 +
>> > ?arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
>> > ?arch/arm/mach-imx/gpc.c ? ? ? ? | ?110 +++
>> > ?arch/arm/mach-imx/mmdc.c ? ? ? ?| ? 71 ++
>> > ?arch/arm/mach-imx/src.c ? ? ? ? | ? 52 +
>> > ?6 files changed, 2240 insertions(+), 0 deletions(-)
>>
>> This is unfortunately still a major problem.
>
> It's so sad to still get this comment. ?Back to Linaro Connect on
> Cambridge, I believe I asked for your opinion on new SoC clock support
> without waiting for the clock framework. ?You said you do not have a
> strong position on this and would defer to others' judgement. ?Then
> I talked to Russell and Grant respectively, and they both agree that
> we should not be blocked by the clock framework. ?That's why I decided
> to start upstreaming imx6q.
>
>> I realize that we don't
>> yet have a good framework to do this with significantly less code,
>> but adding a platform that is mostly consisting of stupid additions
>> of clock descriptions that really should be in the device tree does
>> not scale much longer.
>
> I definitely agree this does not scale for long term. ?And I would
> immediately migrate it to clock framework once it gets ready and put
> the description into device tree when clock binding is ready. ?Before
> we get there, we need a way out. ?It's unreasonable for us to hold
> the new soc support for an unspecified time. ?It's been 20 months since
> we saw the common clock patches[1] from Jeremy, and we do not know yet
> how many months we still have to wait. ?Grant worked out the auxdata to
> remove the device tree dependency on clock framework. ?I think we
> should not get new soc support blocked by clock framework either.
>
>> We decided to let this still get in for prima2,
>> which was also ugly in this regard but much simpler than imx6.
>>
> It's unfair to me that you reject imx6q clock code just because it's
> an implementation for a hardware complexer than prima2.

i understand your feeling.

actually i am also waiting for the common clock framework to finish
the whole prima2 clock tree driver. now prima2 only includes a little
part of clock trees, actually if i list all of them, the file will be
large too. And codes are ugly too.

auxdata is really a temp solution, it really brings many details to
kernel, which should not be in kernel at all.

>
>> My feeling is that this time, we should wait for the common clock
>> framework to get in and simplify this. I believe Thomas is now planning
>> to do this, but I haven't followed what the current state is.
>>
> Sadly, if this is the position of entire arm-soc maintainer group,
> I think I have made a wrong decision to start upstreaming imx6q now.
>
>> The other three drivers in this patch are basically ok, so you can
>> definitely post them as a separate patch and perhaps get minor comments
>> for those, similar to what I commented on the other patches.
>>
>> For the clock-imx6q.c file, what I first want to hear from someone
>> is how this is supposed to look like in the long run with device tree
>> integration, and how far away from that we are.
>>
>> Can you comment on how far we get without the clock driver with imx6?
>> Is is basically useless, or is there a way we can merge the remaining
>> imx6 code and other drivers but postpone the large clock driver?
>>
> Unfortunately, clock is pretty fundamental for imx6q support. ?Without
> clock support, imx6q platform is useless. ?We have a real example here.
> Back to Dec. 2010, Sascha refused to take clock patch when Freescale
> was submitting imx50 platform support, because he thought the clock
> framework will get merged pretty soon. ?But we end up with the facts
> that clock framework is still up in the air and imx50 platform support
> on mainline is totally useless.
>
> I have been tried very hard to reduce the LOC of clock-imx6q.c. ?It's
> a 5K LOC file in the Freescale internal tree. ?Now it's 2K LOC. ?I know
> it's still large enough for you to dislike it. ?But this is the clock
> that the hardware has. ?I'm afraid we can not do much to reduce the LOC
> significantly, unless we only implement the small portion other than
> the full clock tree, which is what I really hate to do.
>
> Regards,
> Shawn
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2010-January/007238.html
>

Thanks
barry

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-06  9:58 ` [PATCH 6/6] arm/imx6q: add suspend/resume support Shawn Guo
  2011-09-06 18:56   ` Arnd Bergmann
@ 2011-09-07 13:50   ` Barry Song
  2011-09-08  6:23     ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Barry Song @ 2011-09-07 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

> +
> +static int imx6q_pm_enter(suspend_state_t state)
> +{
> + ? ? ? switch (state) {
> + ? ? ? case PM_SUSPEND_MEM:
> + ? ? ? ? ? ? ? imx_local_timer_pre_suspend();
> + ? ? ? ? ? ? ? imx_gpc_pre_suspend();
> + ? ? ? ? ? ? ? outer_flush_all();
> + ? ? ? ? ? ? ? outer_disable();
> + ? ? ? ? ? ? ? imx_set_cpu_jump(0, v7_cpu_resume);
> +
> + ? ? ? ? ? ? ? /* Zzz ... */
> + ? ? ? ? ? ? ? cpu_suspend(0, imx6q_suspend_finish);
> +
> + ? ? ? ? ? ? ? imx_smp_prepare();
> + ? ? ? ? ? ? ? l2x0_of_init(0, ~0UL);

it is pretty clear and good. i think we can refine
arch/arm/mach-prima2/pm.c to the way you are suspending/resuming l2.
on prima2, l2 will totally lose power in suspend cycle. i remember you
once said imx6q will retain l2 in suspend cycle?

> + ? ? ? ? ? ? ? imx_gpc_post_resume();
> + ? ? ? ? ? ? ? imx_local_timer_post_resume();
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
thanks
barry

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 12:36       ` Uwe Kleine-König
@ 2011-09-07 14:23         ` Russell King - ARM Linux
  2011-09-07 15:36           ` Nicolas Pitre
  2011-09-12  2:30         ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-07 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> But only if the image doesn't support imx6q, right? Anyhow, I hope
> imx6q_map_io isn't called for pre-imx6q SoCs. Ah, and I hope we don't
> need to argue here as Russell doesn't like the new DEBUG_LL changes :-)

I have no problem with the Kconfig menu approach or existing approaches
to DEBUG_LL.  What I have an objection to is trying to stuff the
information for it into places which ultimately render the facility
useless for its intended purpose - to permit debugging the _really_
_early_ assembly code.

That is what it was written for: if we introduce complicated ways to
put behind it, we'll need to come up with a completely new debugging
infrastructure to debug the now buggered debugging infrastructure.

And then people will want to do the same to the debug debugging
infrastructure.  Then we'll have to invent the debug debugging debugging
infrastructure.  Repeat until you've nested it a million times.

It's supposed to be _simple_ and _obviously_ correct so that it _works_
with minimal fuss.  Making it complicated by picking out information
from device trees will kill that, and at that point its not worth keeping
around anymore.

Let me give you an instance: your kernel doesn't boot.  Early printk
doesn't work.  You want to find out if control is even getting to the
very first instruction in head.S.  You can do that with DEBUG_LL as it
stands today because we know exactly where the serial port is supposed
to be.

If you have to pick the DEBUG_LL information out of a DT, you can no
longer do that - you first have to obtain the pointer to DT, and then
parse the DT table to find out where the hell the port is.  What if
the reason your kernel isn't booting is because the DT pointer is
wrong?  What if the reason your kernel isn't booting is because the
information contained within DT is wrong?

How do you debug that?  You probably end up having to write your own
debugging infrastructure using a fixed address for the port.
Congratulations - you just reinvented what DEBUG_LL was designed to
be doing before someone came along and totally buggered it up.

The fact that DEBUG_LL is hard-coded to a certain port address is one
of its strongest points.  It means that if you know that the port
address is correct (which is a matter of looking at the SoCs data
sheets and confirming that the hex digits match) then you can be
reasonably sure that you're going to get some output from it.  No
need to wonder "Is the DT pointer correct?  Are we parsing DT
properly?" etc.

So, either we keep it in its current form or we throw it out from
mainline entirely and I keep it as a separate add-on patch for those
who want to use it.

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 14:23         ` Russell King - ARM Linux
@ 2011-09-07 15:36           ` Nicolas Pitre
  2011-09-08 14:56             ` Arnd Bergmann
  0 siblings, 1 reply; 69+ messages in thread
From: Nicolas Pitre @ 2011-09-07 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 7 Sep 2011, Russell King - ARM Linux wrote:

> On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> > But only if the image doesn't support imx6q, right? Anyhow, I hope
> > imx6q_map_io isn't called for pre-imx6q SoCs. Ah, and I hope we don't
> > need to argue here as Russell doesn't like the new DEBUG_LL changes :-)
> 
> I have no problem with the Kconfig menu approach or existing approaches
> to DEBUG_LL.  What I have an objection to is trying to stuff the
> information for it into places which ultimately render the facility
> useless for its intended purpose - to permit debugging the _really_
> _early_ assembly code.
> 
> That is what it was written for: if we introduce complicated ways to
> put behind it, we'll need to come up with a completely new debugging
> infrastructure to debug the now buggered debugging infrastructure.

For the record I now agree with Russell.

In order to have early serial output that works across multiple SOCs in 
the same kernel image intended to non developers we'll have to add a 
parallel infrastructure.  Keeping the DEBUG_LL code as simple as 
possible for developers is the way to go (and that might be needed to 
debug that parallel infrastructure).


Nicolas

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-07 13:50   ` Barry Song
@ 2011-09-08  6:23     ` Shawn Guo
  2011-09-08  7:47       ` Russell King - ARM Linux
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-08  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 09:50:44PM +0800, Barry Song wrote:
> > +
> > +static int imx6q_pm_enter(suspend_state_t state)
> > +{
> > + ? ? ? switch (state) {
> > + ? ? ? case PM_SUSPEND_MEM:
> > + ? ? ? ? ? ? ? imx_local_timer_pre_suspend();
> > + ? ? ? ? ? ? ? imx_gpc_pre_suspend();
> > + ? ? ? ? ? ? ? outer_flush_all();
> > + ? ? ? ? ? ? ? outer_disable();
> > + ? ? ? ? ? ? ? imx_set_cpu_jump(0, v7_cpu_resume);
> > +
> > + ? ? ? ? ? ? ? /* Zzz ... */
> > + ? ? ? ? ? ? ? cpu_suspend(0, imx6q_suspend_finish);
> > +
> > + ? ? ? ? ? ? ? imx_smp_prepare();
> > + ? ? ? ? ? ? ? l2x0_of_init(0, ~0UL);
> 
> it is pretty clear and good. i think we can refine
> arch/arm/mach-prima2/pm.c to the way you are suspending/resuming l2.
> on prima2, l2 will totally lose power in suspend cycle. i remember you
> once said imx6q will retain l2 in suspend cycle?
> 
Yes, if you lose L2 power in suspend, it's the easiest way for you to
resume L2.

For my case which retains L2, I actually do not want to call this
function which will invalidate L2.  But since we still have problem
to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
cleaning for suspend), we have to flush the entire L2 on imx6q for now.

Regards,
Shawn

> > + ? ? ? ? ? ? ? imx_gpc_post_resume();
> > + ? ? ? ? ? ? ? imx_local_timer_post_resume();
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? default:
> > + ? ? ? ? ? ? ? return -EINVAL;
> > + ? ? ? }
> > +
> > + ? ? ? return 0;
> > +}
> thanks
> barry
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-07 12:43       ` Barry Song
@ 2011-09-08  6:48         ` Shawn Guo
  2011-09-11  2:28           ` Barry Song
  2011-09-12 19:16           ` Grant Likely
  0 siblings, 2 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-08  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 08:43:06PM +0800, Barry Song wrote:
> 2011/9/7 Shawn Guo <shawn.guo@freescale.com>:
> > Hi Arnd,
> >
> > On Tue, Sep 06, 2011 at 09:14:29PM +0200, Arnd Bergmann wrote:
> >> On Tuesday 06 September 2011 17:58:37 Shawn Guo wrote:
> >> > It adds a number of core drivers support for imx6q, including clock,
> >> > General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
> >> > System Reset Controller (src).
> >> >
> >> > Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
> >> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> >> > ---
> >> > ?arch/arm/mach-imx/Kconfig ? ? ? | ? 13 +
> >> > ?arch/arm/mach-imx/Makefile ? ? ?| ? ?4 +
> >> > ?arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
> >> > ?arch/arm/mach-imx/gpc.c ? ? ? ? | ?110 +++
> >> > ?arch/arm/mach-imx/mmdc.c ? ? ? ?| ? 71 ++
> >> > ?arch/arm/mach-imx/src.c ? ? ? ? | ? 52 +
> >> > ?6 files changed, 2240 insertions(+), 0 deletions(-)
> >>
> >> This is unfortunately still a major problem.
> >
> > It's so sad to still get this comment. ?Back to Linaro Connect on
> > Cambridge, I believe I asked for your opinion on new SoC clock support
> > without waiting for the clock framework. ?You said you do not have a
> > strong position on this and would defer to others' judgement. ?Then
> > I talked to Russell and Grant respectively, and they both agree that
> > we should not be blocked by the clock framework. ?That's why I decided
> > to start upstreaming imx6q.
> >
> >> I realize that we don't
> >> yet have a good framework to do this with significantly less code,
> >> but adding a platform that is mostly consisting of stupid additions
> >> of clock descriptions that really should be in the device tree does
> >> not scale much longer.
> >
> > I definitely agree this does not scale for long term. ?And I would
> > immediately migrate it to clock framework once it gets ready and put
> > the description into device tree when clock binding is ready. ?Before
> > we get there, we need a way out. ?It's unreasonable for us to hold
> > the new soc support for an unspecified time. ?It's been 20 months since
> > we saw the common clock patches[1] from Jeremy, and we do not know yet
> > how many months we still have to wait. ?Grant worked out the auxdata to
> > remove the device tree dependency on clock framework. ?I think we
> > should not get new soc support blocked by clock framework either.
> >
> >> We decided to let this still get in for prima2,
> >> which was also ugly in this regard but much simpler than imx6.
> >>
> > It's unfair to me that you reject imx6q clock code just because it's
> > an implementation for a hardware complexer than prima2.
> 
> i understand your feeling.
> 
No, you do not :)  With the talking at Cambridge, I thought I'm allowed
to add new platform support without being blocked by clock framework.
That's why I have been worked very hard for 3 weeks to come up with
this patch series.  Now I'm getting a "no", which really frustrates me.

> actually i am also waiting for the common clock framework to finish
> the whole prima2 clock tree driver. now prima2 only includes a little
> part of clock trees, actually if i list all of them, the file will be
> large too. And codes are ugly too.
> 
I did not hear "ugly" from Arnd on imx6q-clock.c.  Instead, he said
the description of the clocks and the tree should be migrated to clock
frame and device tree clock bindings, which unfortunately have not been
available yet.

> auxdata is really a temp solution, it really brings many details to
> kernel, which should not be in kernel at all.
> 
The auxdata was originally designed to be a temp solution.  But we
will see if it's really temp, considering it could also be used to
carry platform callbacks and attach device id.  There are some other
cases beside clock lookup that we have not been able to sort out just
by device tree and will probably have to use auxdata as well.

-- 
Regards,
Shawn

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08  6:23     ` Shawn Guo
@ 2011-09-08  7:47       ` Russell King - ARM Linux
  2011-09-08 15:22         ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-08  7:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> Yes, if you lose L2 power in suspend, it's the easiest way for you to
> resume L2.
> 
> For my case which retains L2, I actually do not want to call this
> function which will invalidate L2.  But since we still have problem
> to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> cleaning for suspend), we have to flush the entire L2 on imx6q for now.

OMAP44xx has the same problem but they re-initialize L2 on resume in
their pre-cpu_resume() assembly code.

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 15:36           ` Nicolas Pitre
@ 2011-09-08 14:56             ` Arnd Bergmann
  2011-09-09 17:28               ` Tony Lindgren
  0 siblings, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-08 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 07 September 2011, Nicolas Pitre wrote:
> On Wed, 7 Sep 2011, Russell King - ARM Linux wrote:
> 
> > On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> > > But only if the image doesn't support imx6q, right? Anyhow, I hope
> > > imx6q_map_io isn't called for pre-imx6q SoCs. Ah, and I hope we don't
> > > need to argue here as Russell doesn't like the new DEBUG_LL changes :-)
> > 
> > I have no problem with the Kconfig menu approach or existing approaches
> > to DEBUG_LL.  What I have an objection to is trying to stuff the
> > information for it into places which ultimately render the facility
> > useless for its intended purpose - to permit debugging the really
> > early assembly code.
> > 
> > That is what it was written for: if we introduce complicated ways to
> > put behind it, we'll need to come up with a completely new debugging
> > infrastructure to debug the now buggered debugging infrastructure.
> 
> For the record I now agree with Russell.
> 
> In order to have early serial output that works across multiple SOCs in 
> the same kernel image intended to non developers we'll have to add a 
> parallel infrastructure.  Keeping the DEBUG_LL code as simple as 
> possible for developers is the way to go (and that might be needed to 
> debug that parallel infrastructure).

Yes, agreed. It should not be too hard to provide more CON_BOOT consoles.
For 8250, this can actually be done already using the code from
drivers/tty/serial/8250_early.c with a custom command line, but there
are better ways to do that in a generic way.

	Arnd

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08  7:47       ` Russell King - ARM Linux
@ 2011-09-08 15:22         ` Shawn Guo
  2011-09-08 16:24           ` Russell King - ARM Linux
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-08 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> > Yes, if you lose L2 power in suspend, it's the easiest way for you to
> > resume L2.
> > 
> > For my case which retains L2, I actually do not want to call this
> > function which will invalidate L2.  But since we still have problem
> > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
> 
> OMAP44xx has the same problem but they re-initialize L2 on resume in
> their pre-cpu_resume() assembly code.
> 
Are you suggesting that this might be the reason why imx6q has problem
with your patch?  Are we supposed to re-initialize L2 before calling
into generic cpu_resume()?

-- 
Regards,
Shawn

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08 15:22         ` Shawn Guo
@ 2011-09-08 16:24           ` Russell King - ARM Linux
  2011-09-08 17:09             ` Lorenzo Pieralisi
                               ` (2 more replies)
  0 siblings, 3 replies; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-08 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 11:22:23PM +0800, Shawn Guo wrote:
> On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
> > On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> > > Yes, if you lose L2 power in suspend, it's the easiest way for you to
> > > resume L2.
> > > 
> > > For my case which retains L2, I actually do not want to call this
> > > function which will invalidate L2.  But since we still have problem
> > > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> > > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
> > 
> > OMAP44xx has the same problem but they re-initialize L2 on resume in
> > their pre-cpu_resume() assembly code.
> > 
> Are you suggesting that this might be the reason why imx6q has problem
> with your patch?

Consider the mechanics of what is happening.

On suspend, when we enter cpu_suspend(), we assume the L2 cache is
still enabled.

We _always_ assume that L1 cache state is lost, so we always flush the
entire L1 cache.

As SoCs can (and do) preserve the L2 contents over suspend/resume cycles,
we leave it to the platform's finisher to decide whether it needs to
flush the entire L2 cache to RAM or not.

If L2 is preserved, then we want to ensure that as much data as possible
is retained in the L2 cache (if the hardware preserves its contents, we
don't want waste time flushing data out of the cache needlessly -
especially if we're using these paths for cpuidle.)  However, we need
access to a certain amount of data to bring the system back up, and as
the L2 cache typically will not be searched before the MMU is enabled,
we have to flush out a certain minimal amount of data (the location
of the stacked restore information and the stacked restore information
itself.)

However, we don't flush out anything else from the L2 cache.

Now, upon resume, the resume code will be able to read the data it needs
to restore the system as we ensured that was flushed out to memory - as
I mentioned above, the L2 cache won't be searched for this irrespective
of whether the control registers have enabled it or not.

We will continue to the point where we hit the first bit of information
stored in L2, which will probably be the stacked SVC register set.  If
at this point we're not able to search the L2 cache, then we'll read
stale data from the backing memory instead, and the system will crash.

Consider what generic code could do about this - if we flushed out that
register set to memory, then we could get past that point - but we then
would need to call a function to enable the L2 cache.  What if that
function needs data which is sitting in the L2 cache to function (eg,
it may need values from the device tree).  We would need to ensure
that that data were also flushed out of the L2 cache.  What about
spinlocks?  Maybe some other CPU has dragged the spinlock data into
the L2 cache.  That gets _much_ harder to solve.

Now to the physical act of enabling the L2 cache.  The L2 cache control
registers are subject to security restrictions when running in non-secure
mode, needing platform specific SMC calls to reprogram the cache.  Generic
code is unable to do this.

Hence why it's left up to the platform to figure out how to enable the
L2 cache before calling cpu_resume().  The platform is best placed to
work out what it needs to do to setup the L2 cache so that the L2 cache
is available by the time the system control register is written, enabling
the MMU and caches.

> Are we supposed to re-initialize L2 before calling
> into generic cpu_resume()?

So, the above is the long way of saying "yes" to this question.  I hope
it gives the full picture about why this is so.

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08 16:24           ` Russell King - ARM Linux
@ 2011-09-08 17:09             ` Lorenzo Pieralisi
  2011-09-09  7:40               ` Shawn Guo
  2011-09-09  6:31             ` Barry Song
  2011-09-09  7:32             ` Shawn Guo
  2 siblings, 1 reply; 69+ messages in thread
From: Lorenzo Pieralisi @ 2011-09-08 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 05:24:52PM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 08, 2011 at 11:22:23PM +0800, Shawn Guo wrote:
> > On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> > > > Yes, if you lose L2 power in suspend, it's the easiest way for you to
> > > > resume L2.
> > > > 
> > > > For my case which retains L2, I actually do not want to call this
> > > > function which will invalidate L2.  But since we still have problem
> > > > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> > > > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
> > > 
> > > OMAP44xx has the same problem but they re-initialize L2 on resume in
> > > their pre-cpu_resume() assembly code.
> > > 
> > Are you suggesting that this might be the reason why imx6q has problem
> > with your patch?
> 
> Consider the mechanics of what is happening.
> 
> On suspend, when we enter cpu_suspend(), we assume the L2 cache is
> still enabled.
> 
> We _always_ assume that L1 cache state is lost, so we always flush the
> entire L1 cache.
> 
> As SoCs can (and do) preserve the L2 contents over suspend/resume cycles,
> we leave it to the platform's finisher to decide whether it needs to
> flush the entire L2 cache to RAM or not.
> 
> If L2 is preserved, then we want to ensure that as much data as possible
> is retained in the L2 cache (if the hardware preserves its contents, we
> don't want waste time flushing data out of the cache needlessly -
> especially if we're using these paths for cpuidle.)  However, we need
> access to a certain amount of data to bring the system back up, and as
> the L2 cache typically will not be searched before the MMU is enabled,
> we have to flush out a certain minimal amount of data (the location
> of the stacked restore information and the stacked restore information
> itself.)
> 
> However, we don't flush out anything else from the L2 cache.
> 
> Now, upon resume, the resume code will be able to read the data it needs
> to restore the system as we ensured that was flushed out to memory - as
> I mentioned above, the L2 cache won't be searched for this irrespective
> of whether the control registers have enabled it or not.
> 
> We will continue to the point where we hit the first bit of information
> stored in L2, which will probably be the stacked SVC register set.  If
> at this point we're not able to search the L2 cache, then we'll read
> stale data from the backing memory instead, and the system will crash.
> 
> Consider what generic code could do about this - if we flushed out that
> register set to memory, then we could get past that point - but we then
> would need to call a function to enable the L2 cache.  What if that
> function needs data which is sitting in the L2 cache to function (eg,
> it may need values from the device tree).  We would need to ensure
> that that data were also flushed out of the L2 cache.  What about
> spinlocks?  Maybe some other CPU has dragged the spinlock data into
> the L2 cache.  That gets _much_ harder to solve.
> 
> Now to the physical act of enabling the L2 cache.  The L2 cache control
> registers are subject to security restrictions when running in non-secure
> mode, needing platform specific SMC calls to reprogram the cache.  Generic
> code is unable to do this.
> 
> Hence why it's left up to the platform to figure out how to enable the
> L2 cache before calling cpu_resume().  The platform is best placed to
> work out what it needs to do to setup the L2 cache so that the L2 cache
> is available by the time the system control register is written, enabling
> the MMU and caches.
> 
> > Are we supposed to re-initialize L2 before calling
> > into generic cpu_resume()?
> 
> So, the above is the long way of saying "yes" to this question.  I hope
> it gives the full picture about why this is so.
> 

I could not agree more. On top of that l2x0_of_init invalidates L2 which is
not what we want on retention. 
Furthermore, parsing the device tree every given suspend, as fast as it can be,
that seems silly to me for registers that will never ever change (maybe perf
counters, but perf will save them). And if they do change parsing them
from the device tree might not be what we want.

Let's save those registers once for all at boot and reprogramme them before 
jumping to cpu_resume, that's by far the best solution.

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08 16:24           ` Russell King - ARM Linux
  2011-09-08 17:09             ` Lorenzo Pieralisi
@ 2011-09-09  6:31             ` Barry Song
  2011-09-09  7:32             ` Shawn Guo
  2 siblings, 0 replies; 69+ messages in thread
From: Barry Song @ 2011-09-09  6:31 UTC (permalink / raw)
  To: linux-arm-kernel

2011/9/9 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> On Thu, Sep 08, 2011 at 11:22:23PM +0800, Shawn Guo wrote:
>> On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
>> > On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
>> > > Yes, if you lose L2 power in suspend, it's the easiest way for you to
>> > > resume L2.
>> > >
>> > > For my case which retains L2, I actually do not want to call this
>> > > function which will invalidate L2. ?But since we still have problem
>> > > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
>> > > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
>> >
>> > OMAP44xx has the same problem but they re-initialize L2 on resume in
>> > their pre-cpu_resume() assembly code.
>> >
>> Are you suggesting that this might be the reason why imx6q has problem
>> with your patch?
>
> Consider the mechanics of what is happening.
>
> On suspend, when we enter cpu_suspend(), we assume the L2 cache is
> still enabled.
>
> We _always_ assume that L1 cache state is lost, so we always flush the
> entire L1 cache.
>
> As SoCs can (and do) preserve the L2 contents over suspend/resume cycles,
> we leave it to the platform's finisher to decide whether it needs to
> flush the entire L2 cache to RAM or not.
>
> If L2 is preserved, then we want to ensure that as much data as possible
> is retained in the L2 cache (if the hardware preserves its contents, we
> don't want waste time flushing data out of the cache needlessly -
> especially if we're using these paths for cpuidle.) ?However, we need
> access to a certain amount of data to bring the system back up, and as
> the L2 cache typically will not be searched before the MMU is enabled,
> we have to flush out a certain minimal amount of data (the location
> of the stacked restore information and the stacked restore information
> itself.)
>
> However, we don't flush out anything else from the L2 cache.
>
> Now, upon resume, the resume code will be able to read the data it needs
> to restore the system as we ensured that was flushed out to memory - as
> I mentioned above, the L2 cache won't be searched for this irrespective
> of whether the control registers have enabled it or not.
>
> We will continue to the point where we hit the first bit of information
> stored in L2, which will probably be the stacked SVC register set. ?If
> at this point we're not able to search the L2 cache, then we'll read
> stale data from the backing memory instead, and the system will crash.
>
> Consider what generic code could do about this - if we flushed out that
> register set to memory, then we could get past that point - but we then
> would need to call a function to enable the L2 cache. ?What if that
> function needs data which is sitting in the L2 cache to function (eg,
> it may need values from the device tree). ?We would need to ensure
> that that data were also flushed out of the L2 cache. ?What about
> spinlocks? ?Maybe some other CPU has dragged the spinlock data into
> the L2 cache. ?That gets _much_ harder to solve.
>
> Now to the physical act of enabling the L2 cache. ?The L2 cache control
> registers are subject to security restrictions when running in non-secure
> mode, needing platform specific SMC calls to reprogram the cache. ?Generic
> code is unable to do this.
>
> Hence why it's left up to the platform to figure out how to enable the
> L2 cache before calling cpu_resume(). ?The platform is best placed to
> work out what it needs to do to setup the L2 cache so that the L2 cache
> is available by the time the system control register is written, enabling
> the MMU and caches.

Thanks for your great document to explain what happen. it is really
clear and good.

but in case l2 is not preserved and it is lost in suspend cycles,  we
will flush all data out of l2 before suspending. and we don't need to
re-enable l2
before calling cpu_resume() too since nobody will hit data in l2 not in memory.
after resuming, we just re-init the l2 like cold boot. then
l2x0_of_init() and moving l2x0_init out of init section might be
suitable?

>
>> Are we supposed to re-initialize L2 before calling
>> into generic cpu_resume()?
>
> So, the above is the long way of saying "yes" to this question. ?I hope
> it gives the full picture about why this is so.
>

thanks
barry

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08 16:24           ` Russell King - ARM Linux
  2011-09-08 17:09             ` Lorenzo Pieralisi
  2011-09-09  6:31             ` Barry Song
@ 2011-09-09  7:32             ` Shawn Guo
  2011-09-09  8:15               ` Russell King - ARM Linux
  2 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-09  7:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

Really appreciate the explanation.

On Thu, Sep 08, 2011 at 05:24:52PM +0100, Russell King - ARM Linux wrote:
> On Thu, Sep 08, 2011 at 11:22:23PM +0800, Shawn Guo wrote:
> > On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> > > > Yes, if you lose L2 power in suspend, it's the easiest way for you to
> > > > resume L2.
> > > > 
> > > > For my case which retains L2, I actually do not want to call this
> > > > function which will invalidate L2.  But since we still have problem
> > > > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> > > > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
> > > 
> > > OMAP44xx has the same problem but they re-initialize L2 on resume in
> > > their pre-cpu_resume() assembly code.
> > > 
> > Are you suggesting that this might be the reason why imx6q has problem
> > with your patch?
> 
> Consider the mechanics of what is happening.
> 
> On suspend, when we enter cpu_suspend(), we assume the L2 cache is
> still enabled.
> 
> We _always_ assume that L1 cache state is lost, so we always flush the
> entire L1 cache.
> 
> As SoCs can (and do) preserve the L2 contents over suspend/resume cycles,
> we leave it to the platform's finisher to decide whether it needs to
> flush the entire L2 cache to RAM or not.
> 
> If L2 is preserved, then we want to ensure that as much data as possible
> is retained in the L2 cache (if the hardware preserves its contents, we
> don't want waste time flushing data out of the cache needlessly -
> especially if we're using these paths for cpuidle.)  However, we need
> access to a certain amount of data to bring the system back up, and as
> the L2 cache typically will not be searched before the MMU is enabled,
> we have to flush out a certain minimal amount of data (the location
> of the stacked restore information and the stacked restore information
> itself.)
> 
> However, we don't flush out anything else from the L2 cache.
> 
> Now, upon resume, the resume code will be able to read the data it needs
> to restore the system as we ensured that was flushed out to memory - as
> I mentioned above, the L2 cache won't be searched for this irrespective
> of whether the control registers have enabled it or not.
> 
> We will continue to the point where we hit the first bit of information
> stored in L2, which will probably be the stacked SVC register set.  If
> at this point we're not able to search the L2 cache, then we'll read
> stale data from the backing memory instead, and the system will crash.
> 
> Consider what generic code could do about this - if we flushed out that
> register set to memory, then we could get past that point - but we then
> would need to call a function to enable the L2 cache.  What if that
> function needs data which is sitting in the L2 cache to function (eg,
> it may need values from the device tree).  We would need to ensure
> that that data were also flushed out of the L2 cache.  What about
> spinlocks?  Maybe some other CPU has dragged the spinlock data into
> the L2 cache.  That gets _much_ harder to solve.
> 
> Now to the physical act of enabling the L2 cache.  The L2 cache control
> registers are subject to security restrictions when running in non-secure
> mode, needing platform specific SMC calls to reprogram the cache.  Generic
> code is unable to do this.
> 
I could be very possibly wrong here.  But isn't the core in secure mode
upon reset?  Do we really have to reprogram L2 through SMC calls there?

> Hence why it's left up to the platform to figure out how to enable the
> L2 cache before calling cpu_resume().  The platform is best placed to
> work out what it needs to do to setup the L2 cache so that the L2 cache
> is available by the time the system control register is written, enabling
> the MMU and caches.
> 
> > Are we supposed to re-initialize L2 before calling
> > into generic cpu_resume()?
> 
> So, the above is the long way of saying "yes" to this question.  I hope
> it gives the full picture about why this is so.
> 
Yes, it does.  Thanks, again.

-- 
Regards,
Shawn

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-08 17:09             ` Lorenzo Pieralisi
@ 2011-09-09  7:40               ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-09  7:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 06:09:02PM +0100, Lorenzo Pieralisi wrote:
> On Thu, Sep 08, 2011 at 05:24:52PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Sep 08, 2011 at 11:22:23PM +0800, Shawn Guo wrote:
> > > On Thu, Sep 08, 2011 at 08:47:18AM +0100, Russell King - ARM Linux wrote:
> > > > On Thu, Sep 08, 2011 at 02:23:02PM +0800, Shawn Guo wrote:
> > > > > Yes, if you lose L2 power in suspend, it's the easiest way for you to
> > > > > resume L2.
> > > > > 
> > > > > For my case which retains L2, I actually do not want to call this
> > > > > function which will invalidate L2.  But since we still have problem
> > > > > to use rmk's generic suspend/resume updates (ARM: pm: add L2 cache
> > > > > cleaning for suspend), we have to flush the entire L2 on imx6q for now.
> > > > 
> > > > OMAP44xx has the same problem but they re-initialize L2 on resume in
> > > > their pre-cpu_resume() assembly code.
> > > > 
> > > Are you suggesting that this might be the reason why imx6q has problem
> > > with your patch?
> > 
> > Consider the mechanics of what is happening.
> > 
> > On suspend, when we enter cpu_suspend(), we assume the L2 cache is
> > still enabled.
> > 
> > We _always_ assume that L1 cache state is lost, so we always flush the
> > entire L1 cache.
> > 
> > As SoCs can (and do) preserve the L2 contents over suspend/resume cycles,
> > we leave it to the platform's finisher to decide whether it needs to
> > flush the entire L2 cache to RAM or not.
> > 
> > If L2 is preserved, then we want to ensure that as much data as possible
> > is retained in the L2 cache (if the hardware preserves its contents, we
> > don't want waste time flushing data out of the cache needlessly -
> > especially if we're using these paths for cpuidle.)  However, we need
> > access to a certain amount of data to bring the system back up, and as
> > the L2 cache typically will not be searched before the MMU is enabled,
> > we have to flush out a certain minimal amount of data (the location
> > of the stacked restore information and the stacked restore information
> > itself.)
> > 
> > However, we don't flush out anything else from the L2 cache.
> > 
> > Now, upon resume, the resume code will be able to read the data it needs
> > to restore the system as we ensured that was flushed out to memory - as
> > I mentioned above, the L2 cache won't be searched for this irrespective
> > of whether the control registers have enabled it or not.
> > 
> > We will continue to the point where we hit the first bit of information
> > stored in L2, which will probably be the stacked SVC register set.  If
> > at this point we're not able to search the L2 cache, then we'll read
> > stale data from the backing memory instead, and the system will crash.
> > 
> > Consider what generic code could do about this - if we flushed out that
> > register set to memory, then we could get past that point - but we then
> > would need to call a function to enable the L2 cache.  What if that
> > function needs data which is sitting in the L2 cache to function (eg,
> > it may need values from the device tree).  We would need to ensure
> > that that data were also flushed out of the L2 cache.  What about
> > spinlocks?  Maybe some other CPU has dragged the spinlock data into
> > the L2 cache.  That gets _much_ harder to solve.
> > 
> > Now to the physical act of enabling the L2 cache.  The L2 cache control
> > registers are subject to security restrictions when running in non-secure
> > mode, needing platform specific SMC calls to reprogram the cache.  Generic
> > code is unable to do this.
> > 
> > Hence why it's left up to the platform to figure out how to enable the
> > L2 cache before calling cpu_resume().  The platform is best placed to
> > work out what it needs to do to setup the L2 cache so that the L2 cache
> > is available by the time the system control register is written, enabling
> > the MMU and caches.
> > 
> > > Are we supposed to re-initialize L2 before calling
> > > into generic cpu_resume()?
> > 
> > So, the above is the long way of saying "yes" to this question.  I hope
> > it gives the full picture about why this is so.
> > 
> 
> I could not agree more. On top of that l2x0_of_init invalidates L2 which is
> not what we want on retention. 
> Furthermore, parsing the device tree every given suspend, as fast as it can be,
> that seems silly to me for registers that will never ever change (maybe perf
> counters, but perf will save them). And if they do change parsing them
> from the device tree might not be what we want.
> 
> Let's save those registers once for all at boot and reprogramme them before 
> jumping to cpu_resume, that's by far the best solution.
> 
For cases like imx6q where L2 content will be retained across the
suspend/resume cycle, I agree that this is the best.  I used
l2x0_of_init() approach for imx6q as a temp workaround, because I
have something to sort out with applying rmk's patches.

However, I still think l2x0_of_init() reinitialization is the best
approach for cases like Prima2 where even L2 content gets lost during
suspend/resume cycle.

-- 
Regards,
Shawn

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-09  7:32             ` Shawn Guo
@ 2011-09-09  8:15               ` Russell King - ARM Linux
  2011-09-09 10:15                 ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-09  8:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 09, 2011 at 03:32:48PM +0800, Shawn Guo wrote:
> > Now to the physical act of enabling the L2 cache.  The L2 cache control
> > registers are subject to security restrictions when running in non-secure
> > mode, needing platform specific SMC calls to reprogram the cache.  Generic
> > code is unable to do this.
>
> I could be very possibly wrong here.  But isn't the core in secure mode
> upon reset?  Do we really have to reprogram L2 through SMC calls there?

It probably will be, but the core won't be running the resume function
directly on reset.  (No ARM CPU does this - not even the pre-security
ones.  They've traditionally run the boot loader first.)

Take a moment to think about this in terms of security of data stored on
the secure side (where there maybe private keys stored.)

The kernel runs in the non-secure side of the partition.  If it were to be
entered on resume in secure mode, it could access those keys.  That would
be a really great security hole, which would make the whole thing pointless.

What would happen is the secure monitor ROM code gets control first, just
like it does at normal boot time on secure devices.  Eventually, the kernel
will gain control but only after the secure monitor has switched to
non-secure mode.

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-09  8:15               ` Russell King - ARM Linux
@ 2011-09-09 10:15                 ` Shawn Guo
  2011-09-09 18:47                   ` Russell King - ARM Linux
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-09 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 09, 2011 at 09:15:20AM +0100, Russell King - ARM Linux wrote:
> On Fri, Sep 09, 2011 at 03:32:48PM +0800, Shawn Guo wrote:
> > > Now to the physical act of enabling the L2 cache.  The L2 cache control
> > > registers are subject to security restrictions when running in non-secure
> > > mode, needing platform specific SMC calls to reprogram the cache.  Generic
> > > code is unable to do this.
> >
> > I could be very possibly wrong here.  But isn't the core in secure mode
> > upon reset?  Do we really have to reprogram L2 through SMC calls there?
> 
> It probably will be, but the core won't be running the resume function
> directly on reset.  (No ARM CPU does this - not even the pre-security
> ones.  They've traditionally run the boot loader first.)
> 
Some naive boot ROM may simply jump to the resume entry address saved
in persistent register.

> Take a moment to think about this in terms of security of data stored on
> the secure side (where there maybe private keys stored.)
> 
> The kernel runs in the non-secure side of the partition.  If it were to be
> entered on resume in secure mode, it could access those keys.  That would
> be a really great security hole, which would make the whole thing pointless.
> 
> What would happen is the secure monitor ROM code gets control first, just
> like it does at normal boot time on secure devices.  Eventually, the kernel
> will gain control but only after the secure monitor has switched to
> non-secure mode.
> 
Then the question is that for given bad boot ROM, whether kernel resume
routine should stand up to fill the hole up.

-- 
Regards,
Shawn

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-08 14:56             ` Arnd Bergmann
@ 2011-09-09 17:28               ` Tony Lindgren
  0 siblings, 0 replies; 69+ messages in thread
From: Tony Lindgren @ 2011-09-09 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

* Arnd Bergmann <arnd@arndb.de> [110908 07:23]:
> On Wednesday 07 September 2011, Nicolas Pitre wrote:
> > On Wed, 7 Sep 2011, Russell King - ARM Linux wrote:
> > 
> > > On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> > > > But only if the image doesn't support imx6q, right? Anyhow, I hope
> > > > imx6q_map_io isn't called for pre-imx6q SoCs. Ah, and I hope we don't
> > > > need to argue here as Russell doesn't like the new DEBUG_LL changes :-)
> > > 
> > > I have no problem with the Kconfig menu approach or existing approaches
> > > to DEBUG_LL.  What I have an objection to is trying to stuff the
> > > information for it into places which ultimately render the facility
> > > useless for its intended purpose - to permit debugging the really
> > > early assembly code.
> > > 
> > > That is what it was written for: if we introduce complicated ways to
> > > put behind it, we'll need to come up with a completely new debugging
> > > infrastructure to debug the now buggered debugging infrastructure.
> > 
> > For the record I now agree with Russell.
> > 
> > In order to have early serial output that works across multiple SOCs in 
> > the same kernel image intended to non developers we'll have to add a 
> > parallel infrastructure.  Keeping the DEBUG_LL code as simple as 
> > possible for developers is the way to go (and that might be needed to 
> > debug that parallel infrastructure).
> 
> Yes, agreed. It should not be too hard to provide more CON_BOOT consoles.
> For 8250, this can actually be done already using the code from
> drivers/tty/serial/8250_early.c with a custom command line, but there
> are better ways to do that in a generic way.

Sounds good to me.

Regards,

Tony

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

* [PATCH 6/6] arm/imx6q: add suspend/resume support
  2011-09-09 10:15                 ` Shawn Guo
@ 2011-09-09 18:47                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-09 18:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 09, 2011 at 06:15:10PM +0800, Shawn Guo wrote:
> On Fri, Sep 09, 2011 at 09:15:20AM +0100, Russell King - ARM Linux wrote:
> > On Fri, Sep 09, 2011 at 03:32:48PM +0800, Shawn Guo wrote:
> > > > Now to the physical act of enabling the L2 cache.  The L2 cache control
> > > > registers are subject to security restrictions when running in non-secure
> > > > mode, needing platform specific SMC calls to reprogram the cache.  Generic
> > > > code is unable to do this.
> > >
> > > I could be very possibly wrong here.  But isn't the core in secure mode
> > > upon reset?  Do we really have to reprogram L2 through SMC calls there?
> > 
> > It probably will be, but the core won't be running the resume function
> > directly on reset.  (No ARM CPU does this - not even the pre-security
> > ones.  They've traditionally run the boot loader first.)
> 
> Some naive boot ROM may simply jump to the resume entry address saved
> in persistent register.

That would mean that the platform code needs to deal with this too - and
it's likely that it too is platform specific.

> Then the question is that for given bad boot ROM, whether kernel resume
> routine should stand up to fill the hole up.

That can only be done with knowledge of the platform (eg, where the
secure mode vectors should be pointed) and so can't be dealt with by
generic code.

I would also imagine that it's also far easier to sort out before we
enable the MMU, rather than dealing with the aftermath of having pulled
secure mode entries from the non-secure world into the caches.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-08  6:48         ` Shawn Guo
@ 2011-09-11  2:28           ` Barry Song
  2011-09-12 19:16           ` Grant Likely
  1 sibling, 0 replies; 69+ messages in thread
From: Barry Song @ 2011-09-11  2:28 UTC (permalink / raw)
  To: linux-arm-kernel

2011/9/8 Shawn Guo <shawn.guo@freescale.com>:
> On Wed, Sep 07, 2011 at 08:43:06PM +0800, Barry Song wrote:
>> 2011/9/7 Shawn Guo <shawn.guo@freescale.com>:
>> > Hi Arnd,
>> >
>> > On Tue, Sep 06, 2011 at 09:14:29PM +0200, Arnd Bergmann wrote:
>> >> On Tuesday 06 September 2011 17:58:37 Shawn Guo wrote:
>> >> > It adds a number of core drivers support for imx6q, including clock,
>> >> > General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
>> >> > System Reset Controller (src).
>> >> >
>> >> > Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
>> >> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>> >> > ---
>> >> > ?arch/arm/mach-imx/Kconfig ? ? ? | ? 13 +
>> >> > ?arch/arm/mach-imx/Makefile ? ? ?| ? ?4 +
>> >> > ?arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
>> >> > ?arch/arm/mach-imx/gpc.c ? ? ? ? | ?110 +++
>> >> > ?arch/arm/mach-imx/mmdc.c ? ? ? ?| ? 71 ++
>> >> > ?arch/arm/mach-imx/src.c ? ? ? ? | ? 52 +
>> >> > ?6 files changed, 2240 insertions(+), 0 deletions(-)
>> >>
>> >> This is unfortunately still a major problem.
>> >
>> > It's so sad to still get this comment. ?Back to Linaro Connect on
>> > Cambridge, I believe I asked for your opinion on new SoC clock support
>> > without waiting for the clock framework. ?You said you do not have a
>> > strong position on this and would defer to others' judgement. ?Then
>> > I talked to Russell and Grant respectively, and they both agree that
>> > we should not be blocked by the clock framework. ?That's why I decided
>> > to start upstreaming imx6q.
>> >
>> >> I realize that we don't
>> >> yet have a good framework to do this with significantly less code,
>> >> but adding a platform that is mostly consisting of stupid additions
>> >> of clock descriptions that really should be in the device tree does
>> >> not scale much longer.
>> >
>> > I definitely agree this does not scale for long term. ?And I would
>> > immediately migrate it to clock framework once it gets ready and put
>> > the description into device tree when clock binding is ready. ?Before
>> > we get there, we need a way out. ?It's unreasonable for us to hold
>> > the new soc support for an unspecified time. ?It's been 20 months since
>> > we saw the common clock patches[1] from Jeremy, and we do not know yet
>> > how many months we still have to wait. ?Grant worked out the auxdata to
>> > remove the device tree dependency on clock framework. ?I think we
>> > should not get new soc support blocked by clock framework either.
>> >
>> >> We decided to let this still get in for prima2,
>> >> which was also ugly in this regard but much simpler than imx6.
>> >>
>> > It's unfair to me that you reject imx6q clock code just because it's
>> > an implementation for a hardware complexer than prima2.
>>
>> i understand your feeling.
>>
> No, you do not :) ?With the talking at Cambridge, I thought I'm allowed
> to add new platform support without being blocked by clock framework.
> That's why I have been worked very hard for 3 weeks to come up with
> this patch series. ?Now I'm getting a "no", which really frustrates me.
>
>> actually i am also waiting for the common clock framework to finish
>> the whole prima2 clock tree driver. now prima2 only includes a little
>> part of clock trees, actually if i list all of them, the file will be
>> large too. And codes are ugly too.
>>
> I did not hear "ugly" from Arnd on imx6q-clock.c. ?Instead, he said
> the description of the clocks and the tree should be migrated to clock
> frame and device tree clock bindings, which unfortunately have not been
> available yet.

i see :-)  might you push other imx6q stuff at first? it looks like
Arnd is really glad with your other files.

>
>> auxdata is really a temp solution, it really brings many details to
>> kernel, which should not be in kernel at all.
>>
> The auxdata was originally designed to be a temp solution. ?But we
> will see if it's really temp, considering it could also be used to
> carry platform callbacks and attach device id. ?There are some other
> cases beside clock lookup that we have not been able to sort out just
> by device tree and will probably have to use auxdata as well.
>
> --
> Regards,
> Shawn
>
>
-barry

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 12:36       ` Uwe Kleine-König
  2011-09-07 14:23         ` Russell King - ARM Linux
@ 2011-09-12  2:30         ` Shawn Guo
  2011-09-12  7:41           ` Uwe Kleine-König
  1 sibling, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-12  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> > On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:

[...]

> > > > diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > new file mode 100644
> > > > index 0000000..7432310
> > > > --- /dev/null
> > > > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > @@ -0,0 +1,29 @@
> > > > +/*
> > > > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > > > + * Copyright 2011 Linaro Ltd.
> > > > + *
> > > > + * 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
> > > > + */
> > > > +
> > > > +#ifndef __MACH_MX6Q_H__
> > > > +#define __MACH_MX6Q_H__
> > > > +
> > > > +/* static mappings */
> > > > +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> > > > +
> > > > +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> > > > +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> > > > +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> > > > +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> > > > +
> > > > +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > > > +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > > > +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > > > +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> > > Depending on the sizes of these memory regions you can use the existing
> > > IMX_IO_P2V here. The conditions are:
> > > 
> > > 	SCU_SIZE <= 0x200000
> Actually this should be 0x100000 as this is the size that is mapped in a
> continous chunk.
> 
> > > 	CCM_SIZE <= 0x4000
> > > 	ANATOP_SIZE <= 0x28000
> > > 	UART4 <= 0x100000
> > > 
> > This is exactly what I dislike about IMX_IO_P2V().  We have to verify
> > all these conditions manually.  Looking at the static mapping below
> I did it semi-manual, I just put your constants for imx6q into my script
> (all with size=0x4000 for now) and it told me:
> 
> ...
>  * mx6q:
>  *	SCU	0x00a00000+0x004000	->	0xf4000000+0x004000
>  *	CCM	0x020c4000+0x004000	->	0xf42c4000+0x004000
>  *	ANATOP	0x020c8000+0x004000	->	0xf42c8000+0x004000
>  *	UART4	0x021f0000+0x004000	->	0xf42f0000+0x004000
> ...
> 
> > (copied from arch/arm/plat-mxc/include/mach/hardware.h), do you think
> > it's really scalable and easy to maintain for the long run?
> At least it provides a way to verify the correctness of the mapping.
> Before I introduced the mapping function there was a conflict IIRC.
> 
> > /*
> >  * This is rather complicated for humans and ugly to verify, but for a machine
> >  * it's OK.  Still more as it is usually only applied to constants.  The upsides
> >  * on using this approach are:
> >  *
> >  *  - same mapping on all i.MX machines
> >  *  - works for assembler, too
> >  *  - no need to nurture #defines for virtual addresses
> >  *
> >  * The downside it, it's hard to verify (but I have a script for that).
> If you want I can provide you that script.
> 
Yes, please. I would use IMX_IO_P2V() in the next post.

[...]

> > #define IMX_IO_P2V(x)	(						\
> > 			0xf4000000 +					\
> > 			(((x) & 0x50000000) >> 6) +			\
> > 			(((x) & 0x0b000000) >> 4) +			\
> > 			(((x) & 0x000fffff)))
> > 
> > > hmm, looking at patch 4 SCU_BASE is determined by a coprocessor
> > > instruction?!
> > 
> > Ah, yes.  The SCU physical base address can be retrieved from
> > coprocessor.
> Is there an advantage in autodetecting the base address?
>  
Any disadvantage for doing so?

-- 
Regards,
Shawn

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-12  2:30         ` Shawn Guo
@ 2011-09-12  7:41           ` Uwe Kleine-König
  2011-09-12  8:43             ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Uwe Kleine-König @ 2011-09-12  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Mon, Sep 12, 2011 at 10:30:01AM +0800, Shawn Guo wrote:
> On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> > On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> > > On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > > > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> 
> [...]
> 
> > > > > diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > > new file mode 100644
> > > > > index 0000000..7432310
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > > @@ -0,0 +1,29 @@
> > > > > +/*
> > > > > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > > > > + * Copyright 2011 Linaro Ltd.
> > > > > + *
> > > > > + * 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
> > > > > + */
> > > > > +
> > > > > +#ifndef __MACH_MX6Q_H__
> > > > > +#define __MACH_MX6Q_H__
> > > > > +
> > > > > +/* static mappings */
> > > > > +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> > > > > +
> > > > > +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> > > > > +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> > > > > +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> > > > > +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> > > > > +
> > > > > +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > > > > +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > > > > +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > > > > +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> > > > Depending on the sizes of these memory regions you can use the existing
> > > > IMX_IO_P2V here. The conditions are:
> > > > 
> > > > 	SCU_SIZE <= 0x200000
> > Actually this should be 0x100000 as this is the size that is mapped in a
> > continous chunk.
> > 
> > > > 	CCM_SIZE <= 0x4000
> > > > 	ANATOP_SIZE <= 0x28000
> > > > 	UART4 <= 0x100000
> > > > 
> > > This is exactly what I dislike about IMX_IO_P2V().  We have to verify
> > > all these conditions manually.  Looking at the static mapping below
> > I did it semi-manual, I just put your constants for imx6q into my script
> > (all with size=0x4000 for now) and it told me:
> > 
> > ...
> >  * mx6q:
> >  *	SCU	0x00a00000+0x004000	->	0xf4000000+0x004000
> >  *	CCM	0x020c4000+0x004000	->	0xf42c4000+0x004000
> >  *	ANATOP	0x020c8000+0x004000	->	0xf42c8000+0x004000
> >  *	UART4	0x021f0000+0x004000	->	0xf42f0000+0x004000
> > ...
> > 
> > > (copied from arch/arm/plat-mxc/include/mach/hardware.h), do you think
> > > it's really scalable and easy to maintain for the long run?
> > At least it provides a way to verify the correctness of the mapping.
> > Before I introduced the mapping function there was a conflict IIRC.
> > 
> > > /*
> > >  * This is rather complicated for humans and ugly to verify, but for a machine
> > >  * it's OK.  Still more as it is usually only applied to constants.  The upsides
> > >  * on using this approach are:
> > >  *
> > >  *  - same mapping on all i.MX machines
> > >  *  - works for assembler, too
> > >  *  - no need to nurture #defines for virtual addresses
> > >  *
> > >  * The downside it, it's hard to verify (but I have a script for that).
> > If you want I can provide you that script.
> > 
> Yes, please. I would use IMX_IO_P2V() in the next post.
I just found a bug in the conflict detection code, so I put it in a
repository to prevent the broken script to enter the archives. You can
find it on

	git://git.pengutronix.de/git/ukl/imx-iop2v.git

> [...]
> 
> > > #define IMX_IO_P2V(x)	(						\
> > > 			0xf4000000 +					\
> > > 			(((x) & 0x50000000) >> 6) +			\
> > > 			(((x) & 0x0b000000) >> 4) +			\
> > > 			(((x) & 0x000fffff)))
> > > 
> > > > hmm, looking at patch 4 SCU_BASE is determined by a coprocessor
> > > > instruction?!
> > > 
> > > Ah, yes.  The SCU physical base address can be retrieved from
> > > coprocessor.
> > Is there an advantage in autodetecting the base address?
> >  
> Any disadvantage for doing so?
It makes

	#define MX6Q_SCU_BASE_ADDR       0x00a00000

superfluous. And in case the real address is different it might make

	IMX_IO_P2V(real scu address) != scu_io_desc.virtual

which makes the scriptable check for conflicts kind of useless and might
come as a surprise.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-12  7:41           ` Uwe Kleine-König
@ 2011-09-12  8:43             ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-12  8:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 09:41:47AM +0200, Uwe Kleine-K?nig wrote:
> Hello Shawn,
> 
> On Mon, Sep 12, 2011 at 10:30:01AM +0800, Shawn Guo wrote:
> > On Wed, Sep 07, 2011 at 02:36:35PM +0200, Uwe Kleine-K?nig wrote:
> > > On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> > > > On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > > > > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> > 
> > [...]
> > 
> > > > > > diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > > > new file mode 100644
> > > > > > index 0000000..7432310
> > > > > > --- /dev/null
> > > > > > +++ b/arch/arm/plat-mxc/include/mach/mx6q.h
> > > > > > @@ -0,0 +1,29 @@
> > > > > > +/*
> > > > > > + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > > > > > + * Copyright 2011 Linaro Ltd.
> > > > > > + *
> > > > > > + * 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
> > > > > > + */
> > > > > > +
> > > > > > +#ifndef __MACH_MX6Q_H__
> > > > > > +#define __MACH_MX6Q_H__
> > > > > > +
> > > > > > +/* static mappings */
> > > > > > +#define IMX6Q_VA(x)		(0xf4000000 + (x))
> > > > > > +
> > > > > > +#define MX6Q_SCU_BASE_ADDR	0x00a00000
> > > > > > +#define MX6Q_CCM_BASE_ADDR	0x020c4000
> > > > > > +#define MX6Q_ANATOP_BASE_ADDR	0x020c8000
> > > > > > +#define MX6Q_UART4_BASE_ADDR	0x021f0000
> > > > > > +
> > > > > > +#define MX6Q_SCU_BASE_VADDR	IMX6Q_VA(MX6Q_SCU_BASE_ADDR)
> > > > > > +#define MX6Q_CCM_BASE_VADDR	IMX6Q_VA(MX6Q_CCM_BASE_ADDR)
> > > > > > +#define MX6Q_ANATOP_BASE_VADDR	IMX6Q_VA(MX6Q_ANATOP_BASE_ADDR)
> > > > > > +#define MX6Q_UART4_BASE_VADDR	IMX6Q_VA(MX6Q_UART4_BASE_ADDR)
> > > > > Depending on the sizes of these memory regions you can use the existing
> > > > > IMX_IO_P2V here. The conditions are:
> > > > > 
> > > > > 	SCU_SIZE <= 0x200000
> > > Actually this should be 0x100000 as this is the size that is mapped in a
> > > continous chunk.
> > > 
> > > > > 	CCM_SIZE <= 0x4000
> > > > > 	ANATOP_SIZE <= 0x28000
> > > > > 	UART4 <= 0x100000
> > > > > 
> > > > This is exactly what I dislike about IMX_IO_P2V().  We have to verify
> > > > all these conditions manually.  Looking at the static mapping below
> > > I did it semi-manual, I just put your constants for imx6q into my script
> > > (all with size=0x4000 for now) and it told me:
> > > 
> > > ...
> > >  * mx6q:
> > >  *	SCU	0x00a00000+0x004000	->	0xf4000000+0x004000
> > >  *	CCM	0x020c4000+0x004000	->	0xf42c4000+0x004000
> > >  *	ANATOP	0x020c8000+0x004000	->	0xf42c8000+0x004000
> > >  *	UART4	0x021f0000+0x004000	->	0xf42f0000+0x004000
> > > ...
> > > 
> > > > (copied from arch/arm/plat-mxc/include/mach/hardware.h), do you think
> > > > it's really scalable and easy to maintain for the long run?
> > > At least it provides a way to verify the correctness of the mapping.
> > > Before I introduced the mapping function there was a conflict IIRC.
> > > 
> > > > /*
> > > >  * This is rather complicated for humans and ugly to verify, but for a machine
> > > >  * it's OK.  Still more as it is usually only applied to constants.  The upsides
> > > >  * on using this approach are:
> > > >  *
> > > >  *  - same mapping on all i.MX machines
> > > >  *  - works for assembler, too
> > > >  *  - no need to nurture #defines for virtual addresses
> > > >  *
> > > >  * The downside it, it's hard to verify (but I have a script for that).
> > > If you want I can provide you that script.
> > > 
> > Yes, please. I would use IMX_IO_P2V() in the next post.
> I just found a bug in the conflict detection code, so I put it in a
> repository to prevent the broken script to enter the archives. You can
> find it on
> 
> 	git://git.pengutronix.de/git/ukl/imx-iop2v.git
> 
Thanks, Uwe.

> > [...]
> > 
> > > > #define IMX_IO_P2V(x)	(						\
> > > > 			0xf4000000 +					\
> > > > 			(((x) & 0x50000000) >> 6) +			\
> > > > 			(((x) & 0x0b000000) >> 4) +			\
> > > > 			(((x) & 0x000fffff)))
> > > > 
> > > > > hmm, looking at patch 4 SCU_BASE is determined by a coprocessor
> > > > > instruction?!
> > > > 
> > > > Ah, yes.  The SCU physical base address can be retrieved from
> > > > coprocessor.
> > > Is there an advantage in autodetecting the base address?
> > >  
> > Any disadvantage for doing so?
> It makes
> 
> 	#define MX6Q_SCU_BASE_ADDR       0x00a00000
> 
> superfluous.

The definition is actually not needed.  I put it there as a
documentation telling SCU is statically mapped.

> And in case the real address is different it might make
> 
> 	IMX_IO_P2V(real scu address) != scu_io_desc.virtual
> 

This should never happen.

One thing I'm trying to do is to keep arch/arm/mach-imx/platsmp.c
not specific to imx6q.  The auto-detecting helps to keep
MX6Q_SCU_BASE_ADDR away from the file, so that one day when we have
another imx smp soc, we can simply reuse the file.

Regards,
Shawn

> which makes the scriptable check for conflicts kind of useless and might
> come as a surprise.
> 

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-07 11:00     ` Shawn Guo
  2011-09-07 12:36       ` Uwe Kleine-König
@ 2011-09-12  8:44       ` Sascha Hauer
  2011-09-12 11:36         ` Shawn Guo
  2011-09-12 14:14         ` Russell King - ARM Linux
  1 sibling, 2 replies; 69+ messages in thread
From: Sascha Hauer @ 2011-09-12  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> > > It adds the core definitions and low-level debug uart support
> > > for imx6q.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > > ---
> > >  arch/arm/Kconfig                             |    2 +-
> > >  arch/arm/Kconfig.debug                       |    7 +++++
> > >  arch/arm/Makefile                            |    1 +
> > >  arch/arm/mach-imx/Kconfig                    |    4 +++
> > >  arch/arm/mach-imx/Makefile                   |    2 +
> > >  arch/arm/mach-imx/Makefile.boot              |    4 +++
> > >  arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
> > >  arch/arm/plat-mxc/Kconfig                    |    5 ++++
> > >  arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
> > >  arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
> > >  arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
> > >  arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
> > >  arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
> > >  arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
> > >  14 files changed, 115 insertions(+), 5 deletions(-)
> > >  create mode 100644 arch/arm/mach-imx/lluart.c
> > >  create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h
> > > 
> > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > > index 4ea9974..37c20a4 100644
> > > --- a/arch/arm/Kconfig
> > > +++ b/arch/arm/Kconfig
> > > @@ -1348,7 +1348,7 @@ config SMP
> > >  	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
> > >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
> > >  		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
> > > -		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
> > > +		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
> > >  	select USE_GENERIC_SMP_HELPERS
> > >  	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
> > >  	help
> > > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > > index 965d59a..68fc155 100644
> > > --- a/arch/arm/Kconfig.debug
> > > +++ b/arch/arm/Kconfig.debug
> > > @@ -155,6 +155,13 @@ choice
> > >  		  Say Y here if you want kernel low-level debugging support
> > >  		  on i.MX50 or i.MX53.
> > >  
> > > +	config DEBUG_IMX6Q_UART
> > > +		bool "i.MX6Q Debug UART"
> > > +		depends on SOC_IMX6Q
> > > +		help
> > > +		  Say Y here if you want kernel low-level debugging support
> > > +		  on i.MX6Q.
> > > +
> > >  	config DEBUG_S3C_UART0
> > >  		depends on PLAT_SAMSUNG
> > >  		bool "Use S3C UART 0 for low-level debug"
> > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > index 70c424e..3a0bbe4 100644
> > > --- a/arch/arm/Makefile
> > > +++ b/arch/arm/Makefile
> > > @@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
> > >  machine-$(CONFIG_ARCH_MX25)		:= imx
> > >  machine-$(CONFIG_ARCH_MX3)		:= imx
> > >  machine-$(CONFIG_ARCH_MX5)		:= mx5
> > > +machine-$(CONFIG_ARCH_MX6)		:= imx
> > >  machine-$(CONFIG_ARCH_MXS)		:= mxs
> > >  machine-$(CONFIG_ARCH_NETX)		:= netx
> > >  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
> > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > > index 0519dd7..4cf5178 100644
> > > --- a/arch/arm/mach-imx/Kconfig
> > > +++ b/arch/arm/mach-imx/Kconfig
> > > @@ -58,6 +58,10 @@ config SOC_IMX35
> > >  	select ARCH_MX35
> > >  	select MXC_AVIC
> > >  
> > > +config SOC_IMX6Q
> > > +	bool
> > > +	select ARM_GIC
> > > +	select CPU_V7
> > >  
> > >  if ARCH_MX1
> > >  
> > > diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> > > index e9eb36d..96ecc96 100644
> > > --- a/arch/arm/mach-imx/Makefile
> > > +++ b/arch/arm/mach-imx/Makefile
> > > @@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
> > >  obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
> > >  obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
> > >  obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> > > +
> > > +obj-$(CONFIG_DEBUG_LL) += lluart.o
> > > diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> > > index ebee18b..389a0e3 100644
> > > --- a/arch/arm/mach-imx/Makefile.boot
> > > +++ b/arch/arm/mach-imx/Makefile.boot
> > > @@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
> > >  zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
> > >  params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
> > >  initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
> > > +
> > > +zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
> > > +params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
> > > +initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
> > Do you really need params_phys and initrd_phys?
> > 
> I added them to make IMX6Q look consistent with other soc in the file,
> and leave it to a global cleanup, if we decide to clean later.

I vote to skip params_phys and initrd_phys now. Every recent bootloader
does not need them. As the i.MX6 is a new SoC, we have no reason to
handle legacy bootloaders. When we want to to a global cleanup for these
variables we already know that i.MX6 has no legacy bootloader problems.

BTW many variables have the name imx6q, I suppose the 'q' is for quad
cpu. From the FSL website I know that there are other versions of the
i.MX6 planned. Are these variables really imx6q specific? Otherwise
please skip the 'q'.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-06  9:58 ` [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src Shawn Guo
  2011-09-06 19:14   ` Arnd Bergmann
@ 2011-09-12  9:46   ` Sascha Hauer
  2011-09-12 11:49     ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Sascha Hauer @ 2011-09-12  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> It adds a number of core drivers support for imx6q, including clock,
> General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
> System Reset Controller (src).
> 
> Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
> diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
> new file mode 100644
> index 0000000..95fdd65
> --- /dev/null
> +++ b/arch/arm/mach-imx/src.c
> @@ -0,0 +1,52 @@
> +/*
> + * Copyright 2011 Freescale Semiconductor, Inc.
> + * Copyright 2011 Linaro Ltd.
> + *
> + * 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 <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <asm/unified.h>
> +
> +#define SRC_SCR				0x000
> +#define SRC_GPR1			0x020
> +#define BP_SRC_SCR_CORE1_RST		14
> +#define BP_SRC_SCR_CORE1_ENABLE		22
> +
> +static void __iomem *src_base;
> +
> +void imx_enable_cpu(int cpu, bool enable)
> +{
> +	u32 mask, val;
> +
> +	mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
> +	val = __raw_readl(src_base + SRC_SCR);
> +	val = enable ? val | mask : val & ~mask;
> +	__raw_writel(val, src_base + SRC_SCR);
> +}
> +
> +void imx_set_cpu_jump(int cpu, void *jump_addr)
> +{
> +	__raw_writel(BSYM(virt_to_phys(jump_addr)),
> +		     src_base + SRC_GPR1 + cpu * 8);
> +}
> +
> +static int __init imx_src_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> +	src_base = of_iomap(np, 0);
> +	WARN_ON(!src_base);
> +
> +	return 0;
> +}
> +early_initcall(imx_src_init);

What I'm concerned about is that we carefully removed all assumptions
about which SoC the code runs on in the past. Now with this patchset
many of them come back. Here we have a initcall without any check
whether we really run on i.MX6. Above we have a imx_enable_cpu function
but this is really a imx6 specific function. Nevertheless it is called
from generic code in arch/arm/mach-imx/platsmp.c.

We've been there before and it was hard to remove all the implicit
assumptions on which SoC we are on. Please do not reintroduce it.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-12  8:44       ` Sascha Hauer
@ 2011-09-12 11:36         ` Shawn Guo
  2011-09-12 14:14         ` Russell King - ARM Linux
  1 sibling, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-12 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 10:44:39AM +0200, Sascha Hauer wrote:
> On Wed, Sep 07, 2011 at 07:00:02PM +0800, Shawn Guo wrote:
> > On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> > > On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:
> > > > It adds the core definitions and low-level debug uart support
> > > > for imx6q.
> > > > 
> > > > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > > > ---
> > > >  arch/arm/Kconfig                             |    2 +-
> > > >  arch/arm/Kconfig.debug                       |    7 +++++
> > > >  arch/arm/Makefile                            |    1 +
> > > >  arch/arm/mach-imx/Kconfig                    |    4 +++
> > > >  arch/arm/mach-imx/Makefile                   |    2 +
> > > >  arch/arm/mach-imx/Makefile.boot              |    4 +++
> > > >  arch/arm/mach-imx/lluart.c                   |   33 ++++++++++++++++++++++++++
> > > >  arch/arm/plat-mxc/Kconfig                    |    5 ++++
> > > >  arch/arm/plat-mxc/include/mach/debug-macro.S |    5 ++++
> > > >  arch/arm/plat-mxc/include/mach/entry-macro.S |   15 +++++++++++-
> > > >  arch/arm/plat-mxc/include/mach/hardware.h    |    1 +
> > > >  arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++--
> > > >  arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
> > > >  arch/arm/plat-mxc/include/mach/mx6q.h        |   29 ++++++++++++++++++++++
> > > >  14 files changed, 115 insertions(+), 5 deletions(-)
> > > >  create mode 100644 arch/arm/mach-imx/lluart.c
> > > >  create mode 100644 arch/arm/plat-mxc/include/mach/mx6q.h
> > > > 
> > > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > > > index 4ea9974..37c20a4 100644
> > > > --- a/arch/arm/Kconfig
> > > > +++ b/arch/arm/Kconfig
> > > > @@ -1348,7 +1348,7 @@ config SMP
> > > >  	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
> > > >  		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
> > > >  		 ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
> > > > -		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
> > > > +		 ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || SOC_IMX6Q
> > > >  	select USE_GENERIC_SMP_HELPERS
> > > >  	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
> > > >  	help
> > > > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> > > > index 965d59a..68fc155 100644
> > > > --- a/arch/arm/Kconfig.debug
> > > > +++ b/arch/arm/Kconfig.debug
> > > > @@ -155,6 +155,13 @@ choice
> > > >  		  Say Y here if you want kernel low-level debugging support
> > > >  		  on i.MX50 or i.MX53.
> > > >  
> > > > +	config DEBUG_IMX6Q_UART
> > > > +		bool "i.MX6Q Debug UART"
> > > > +		depends on SOC_IMX6Q
> > > > +		help
> > > > +		  Say Y here if you want kernel low-level debugging support
> > > > +		  on i.MX6Q.
> > > > +
> > > >  	config DEBUG_S3C_UART0
> > > >  		depends on PLAT_SAMSUNG
> > > >  		bool "Use S3C UART 0 for low-level debug"
> > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > > index 70c424e..3a0bbe4 100644
> > > > --- a/arch/arm/Makefile
> > > > +++ b/arch/arm/Makefile
> > > > @@ -159,6 +159,7 @@ machine-$(CONFIG_ARCH_MX2)		:= imx
> > > >  machine-$(CONFIG_ARCH_MX25)		:= imx
> > > >  machine-$(CONFIG_ARCH_MX3)		:= imx
> > > >  machine-$(CONFIG_ARCH_MX5)		:= mx5
> > > > +machine-$(CONFIG_ARCH_MX6)		:= imx
> > > >  machine-$(CONFIG_ARCH_MXS)		:= mxs
> > > >  machine-$(CONFIG_ARCH_NETX)		:= netx
> > > >  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
> > > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > > > index 0519dd7..4cf5178 100644
> > > > --- a/arch/arm/mach-imx/Kconfig
> > > > +++ b/arch/arm/mach-imx/Kconfig
> > > > @@ -58,6 +58,10 @@ config SOC_IMX35
> > > >  	select ARCH_MX35
> > > >  	select MXC_AVIC
> > > >  
> > > > +config SOC_IMX6Q
> > > > +	bool
> > > > +	select ARM_GIC
> > > > +	select CPU_V7
> > > >  
> > > >  if ARCH_MX1
> > > >  
> > > > diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> > > > index e9eb36d..96ecc96 100644
> > > > --- a/arch/arm/mach-imx/Makefile
> > > > +++ b/arch/arm/mach-imx/Makefile
> > > > @@ -61,3 +61,5 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
> > > >  obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
> > > >  obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
> > > >  obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> > > > +
> > > > +obj-$(CONFIG_DEBUG_LL) += lluart.o
> > > > diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> > > > index ebee18b..389a0e3 100644
> > > > --- a/arch/arm/mach-imx/Makefile.boot
> > > > +++ b/arch/arm/mach-imx/Makefile.boot
> > > > @@ -17,3 +17,7 @@ initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
> > > >  zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
> > > >  params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
> > > >  initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
> > > > +
> > > > +zreladdr-$(CONFIG_SOC_IMX6Q)	:= 0x10008000
> > > > +params_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10000100
> > > > +initrd_phys-$(CONFIG_SOC_IMX6Q)	:= 0x10800000
> > > Do you really need params_phys and initrd_phys?
> > > 
> > I added them to make IMX6Q look consistent with other soc in the file,
> > and leave it to a global cleanup, if we decide to clean later.
> 
> I vote to skip params_phys and initrd_phys now. Every recent bootloader
> does not need them. As the i.MX6 is a new SoC, we have no reason to
> handle legacy bootloaders. When we want to to a global cleanup for these
> variables we already know that i.MX6 has no legacy bootloader problems.
> 
Ok.

> BTW many variables have the name imx6q, I suppose the 'q' is for quad
> cpu. From the FSL website I know that there are other versions of the
> i.MX6 planned. Are these variables really imx6q specific? Otherwise
> please skip the 'q'.
> 
Before other imx6 family SoCs come to world, we really do not know what
are imx6q specific and what are not.

-- 
Regards,
Shawn

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12  9:46   ` Sascha Hauer
@ 2011-09-12 11:49     ` Shawn Guo
  2011-09-12 12:36       ` Uwe Kleine-König
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-12 11:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 11:46:34AM +0200, Sascha Hauer wrote:
> On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> > It adds a number of core drivers support for imx6q, including clock,
> > General Power Controller (gpc), Multi Mode DDR Controller(mmdc) and
> > System Reset Controller (src).
> > 
> > Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> > diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
> > new file mode 100644
> > index 0000000..95fdd65
> > --- /dev/null
> > +++ b/arch/arm/mach-imx/src.c
> > @@ -0,0 +1,52 @@
> > +/*
> > + * Copyright 2011 Freescale Semiconductor, Inc.
> > + * Copyright 2011 Linaro Ltd.
> > + *
> > + * 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 <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <asm/unified.h>
> > +
> > +#define SRC_SCR				0x000
> > +#define SRC_GPR1			0x020
> > +#define BP_SRC_SCR_CORE1_RST		14
> > +#define BP_SRC_SCR_CORE1_ENABLE		22
> > +
> > +static void __iomem *src_base;
> > +
> > +void imx_enable_cpu(int cpu, bool enable)
> > +{
> > +	u32 mask, val;
> > +
> > +	mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
> > +	val = __raw_readl(src_base + SRC_SCR);
> > +	val = enable ? val | mask : val & ~mask;
> > +	__raw_writel(val, src_base + SRC_SCR);
> > +}
> > +
> > +void imx_set_cpu_jump(int cpu, void *jump_addr)
> > +{
> > +	__raw_writel(BSYM(virt_to_phys(jump_addr)),
> > +		     src_base + SRC_GPR1 + cpu * 8);
> > +}
> > +
> > +static int __init imx_src_init(void)
> > +{
> > +	struct device_node *np;
> > +
> > +	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> > +	src_base = of_iomap(np, 0);
> > +	WARN_ON(!src_base);
> > +
> > +	return 0;
> > +}
> > +early_initcall(imx_src_init);
> 
> What I'm concerned about is that we carefully removed all assumptions
> about which SoC the code runs on in the past. Now with this patchset
> many of them come back. Here we have a initcall without any check
> whether we really run on i.MX6.

The "check" has been done on Kconfig level as below.

config SOC_IMX6Q
        bool "i.MX6 Quad support"
        select HAVE_IMX_SRC

obj-$(CONFIG_HAVE_IMX_SRC) += src.o


> Above we have a imx_enable_cpu function
> but this is really a imx6 specific function.

I would say this is a imx smp specific function.

> Nevertheless it is called
> from generic code in arch/arm/mach-imx/platsmp.c.
> 
> We've been there before and it was hard to remove all the implicit
> assumptions on which SoC we are on. Please do not reintroduce it.
> 
We create platform driver for (talking to) specific device (IP block),
and select the driver for SoCs that have the device.  Anything wrong
with this approach?  Or I missed your point here?

-- 
Regards,
Shawn

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 11:49     ` Shawn Guo
@ 2011-09-12 12:36       ` Uwe Kleine-König
  2011-09-12 12:40         ` Arnd Bergmann
  0 siblings, 1 reply; 69+ messages in thread
From: Uwe Kleine-König @ 2011-09-12 12:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Mon, Sep 12, 2011 at 07:49:33PM +0800, Shawn Guo wrote:
> On Mon, Sep 12, 2011 at 11:46:34AM +0200, Sascha Hauer wrote:
> > On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> > > +static int __init imx_src_init(void)
> > > +{
> > > +	struct device_node *np;
> > > +
> > > +	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> > > +	src_base = of_iomap(np, 0);
> > > +	WARN_ON(!src_base);
> > > +
> > > +	return 0;
> > > +}
> > > +early_initcall(imx_src_init);
> > 
> > What I'm concerned about is that we carefully removed all assumptions
> > about which SoC the code runs on in the past. Now with this patchset
> > many of them come back. Here we have a initcall without any check
> > whether we really run on i.MX6.
> 
> The "check" has been done on Kconfig level as below.
> 
> config SOC_IMX6Q
>         bool "i.MX6 Quad support"
>         select HAVE_IMX_SRC
> 
> obj-$(CONFIG_HAVE_IMX_SRC) += src.o
Think multi-SoC-kernel that has SOC_IMX6Q and say SOC_IMX51.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 12:36       ` Uwe Kleine-König
@ 2011-09-12 12:40         ` Arnd Bergmann
  2011-09-12 14:27           ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-12 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 12 September 2011, Uwe Kleine-K?nig wrote:
> On Mon, Sep 12, 2011 at 07:49:33PM +0800, Shawn Guo wrote:
> > On Mon, Sep 12, 2011 at 11:46:34AM +0200, Sascha Hauer wrote:
> > > On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> > > > +static int __init imx_src_init(void)
> > > > +{
> > > > + struct device_node *np;
> > > > +
> > > > + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> > > > + src_base = of_iomap(np, 0);
> > > > + WARN_ON(!src_base);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +early_initcall(imx_src_init);
> > > 
> > > What I'm concerned about is that we carefully removed all assumptions
> > > about which SoC the code runs on in the past. Now with this patchset
> > > many of them come back. Here we have a initcall without any check
> > > whether we really run on i.MX6.
> > 
> > The "check" has been done on Kconfig level as below.
> > 
> > config SOC_IMX6Q
> >         bool "i.MX6 Quad support"
> >         select HAVE_IMX_SRC
> > 
> > obj-$(CONFIG_HAVE_IMX_SRC) += src.o
> Think multi-SoC-kernel that has SOC_IMX6Q and say SOC_IMX51.

I think the code is almost ok, since it's only active when there is
a "fsl,imx6q-src" device node. However, the WARN_ON must be removed
if we want this to work well on a multi-soc kernel.

The more important point is to ensure that src_base is not being used
on other SoCs, but that's probably covered as well.

	Arnd

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-12  8:44       ` Sascha Hauer
  2011-09-12 11:36         ` Shawn Guo
@ 2011-09-12 14:14         ` Russell King - ARM Linux
  2011-09-17 11:59           ` Russell King - ARM Linux
  1 sibling, 1 reply; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-12 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 10:44:39AM +0200, Sascha Hauer wrote:
> I vote to skip params_phys and initrd_phys now. Every recent bootloader
> does not need them. As the i.MX6 is a new SoC, we have no reason to
> handle legacy bootloaders.

Can we stop this misunderstanding right now.

It's NOT about legacy boot loaders.  It's about the bootp code which
allows an initrd to be packaged up together with a zImage file as one
single file.

That's used to be able to boot with an initrd on platforms which can
only obtain one file from the boot media, and they specify where the
parameters are expected to be (which can be solved by updating the
code to use r2) and where to place the initrd image (which can't be
solved as it would mean encoding memory information for every platform
into the bootp code.)

An example of a current boot loader which requires this: Simtec's Able
boot loader.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 12:40         ` Arnd Bergmann
@ 2011-09-12 14:27           ` Shawn Guo
  2011-09-15  1:26             ` Shawn Guo
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-12 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 02:40:35PM +0200, Arnd Bergmann wrote:
> On Monday 12 September 2011, Uwe Kleine-K?nig wrote:
> > On Mon, Sep 12, 2011 at 07:49:33PM +0800, Shawn Guo wrote:
> > > On Mon, Sep 12, 2011 at 11:46:34AM +0200, Sascha Hauer wrote:
> > > > On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> > > > > +static int __init imx_src_init(void)
> > > > > +{
> > > > > + struct device_node *np;
> > > > > +
> > > > > + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> > > > > + src_base = of_iomap(np, 0);
> > > > > + WARN_ON(!src_base);
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +early_initcall(imx_src_init);
> > > > 
> > > > What I'm concerned about is that we carefully removed all assumptions
> > > > about which SoC the code runs on in the past. Now with this patchset
> > > > many of them come back. Here we have a initcall without any check
> > > > whether we really run on i.MX6.
> > > 
> > > The "check" has been done on Kconfig level as below.
> > > 
> > > config SOC_IMX6Q
> > >         bool "i.MX6 Quad support"
> > >         select HAVE_IMX_SRC
> > > 
> > > obj-$(CONFIG_HAVE_IMX_SRC) += src.o
> > Think multi-SoC-kernel that has SOC_IMX6Q and say SOC_IMX51.
> 
Aha, I did miss the point.  I was misled by "Now with this patchset
many of them come back".  SRC is the only one being called by initcall.
MMDC is a real platform driver.  GPC and Clock init are called by
specific platform code.

> I think the code is almost ok, since it's only active when there is
> a "fsl,imx6q-src" device node. However, the WARN_ON must be removed
> if we want this to work well on a multi-soc kernel.
> 
> The more important point is to ensure that src_base is not being used
> on other SoCs, but that's probably covered as well.
> 
Thanks, Arnd.

-- 
Regards,
Shawn

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-07  7:56       ` Arnd Bergmann
@ 2011-09-12 16:12         ` Shawn Guo
  2011-09-12 19:40           ` Grant Likely
  0 siblings, 1 reply; 69+ messages in thread
From: Shawn Guo @ 2011-09-12 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2011 at 09:56:21AM +0200, Arnd Bergmann wrote:
> On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:
> 
> > > >  arch/arm/mach-imx/Kconfig       |   13 +
> > > >  arch/arm/mach-imx/Makefile      |    4 +
> > > >  arch/arm/mach-imx/clock-imx6q.c | 1990 +++++++++++++++++++++++++++++++++++++++
> > > >  arch/arm/mach-imx/gpc.c         |  110 +++
> > > >  arch/arm/mach-imx/mmdc.c        |   71 ++
> > > >  arch/arm/mach-imx/src.c         |   52 +
> > > >  6 files changed, 2240 insertions(+), 0 deletions(-)
> > > 
> > > This is unfortunately still a major problem.
> > 
> > It's so sad to still get this comment.  Back to Linaro Connect on
> > Cambridge, I believe I asked for your opinion on new SoC clock support
> > without waiting for the clock framework.  You said you do not have a
> > strong position on this and would defer to others' judgement.  Then
> > I talked to Russell and Grant respectively, and they both agree that
> > we should not be blocked by the clock framework.  That's why I decided
> > to start upstreaming imx6q.
> 
> I don't mind being overruled on this if Russell, Grant or others have a good
> feeling about the clock code going in like this.
> 
> I thought that the discussion we had in Cambridge was about migrating the
> existing i.mx code to device tree without waiting for the clock framework.
> If I misremember that and we had actually made a different decision back
> then, then please forgive my overreaction.
> 
> > > I realize that we don't
> > > yet have a good framework to do this with significantly less code,
> > > but adding a platform that is mostly consisting of stupid additions
> > > of clock descriptions that really should be in the device tree does
> > > not scale much longer.
> > 
> > I definitely agree this does not scale for long term.  And I would
> > immediately migrate it to clock framework once it gets ready and put
> > the description into device tree when clock binding is ready.  Before
> > we get there, we need a way out.  It's unreasonable for us to hold
> > the new soc support for an unspecified time.  It's been 20 months since
> > we saw the common clock patches[1] from Jeremy, and we do not know yet
> > how many months we still have to wait.  Grant worked out the auxdata to
> > remove the device tree dependency on clock framework.  I think we
> > should not get new soc support blocked by clock framework either.
> > 
> > > We decided to let this still get in for prima2,
> > > which was also ugly in this regard but much simpler than imx6.
> > > 
> > It's unfair to me that you reject imx6q clock code just because it's
> > an implementation for a hardware complexer than prima2.
> 
> We have to stop taking new platform clock code at some point and get
> all new platforms to use common code as much as possible. The unresolved
> question here is when that will be. My feeling is that prima2 was
> borderline and this is too far, but I may be pushing it here given
> that we are still waiting for the clock framework to actually get
> merged.
> 
> However, if there is no pressure at all, we might never see that framework.
> 
> > > My feeling is that this time, we should wait for the common clock
> > > framework to get in and simplify this. I believe Thomas is now planning
> > > to do this, but I haven't followed what the current state is.
> > > 
> > Sadly, if this is the position of entire arm-soc maintainer group,
> > I think I have made a wrong decision to start upstreaming imx6q now.
> 
> We haven't discussed it as a group, it's my own opinion.
> 

Hi Thomas, Grant,

Could you please share your opinion here?

I really do not see the hope that clock framework and device tree
binding could possibly catch v3.2 window, while I'm hoping that imx6q
series can go into v3.2.

Can you please agree that we can let the imx6q clock code in and then
migrate it to clock framework and device tree once they get ready?

Regards,
Shawn

> > > The other three drivers in this patch are basically ok, so you can
> > > definitely post them as a separate patch and perhaps get minor comments
> > > for those, similar to what I commented on the other patches.
> > > 
> > > For the clock-imx6q.c file, what I first want to hear from someone
> > > is how this is supposed to look like in the long run with device tree
> > > integration, and how far away from that we are.
> > > 
> > > Can you comment on how far we get without the clock driver with imx6?
> > > Is is basically useless, or is there a way we can merge the remaining
> > > imx6 code and other drivers but postpone the large clock driver?
> > > 
> > Unfortunately, clock is pretty fundamental for imx6q support.  Without
> > clock support, imx6q platform is useless.  We have a real example here.
> > Back to Dec. 2010, Sascha refused to take clock patch when Freescale
> > was submitting imx50 platform support, because he thought the clock
> > framework will get merged pretty soon.  But we end up with the facts
> > that clock framework is still up in the air and imx50 platform support
> > on mainline is totally useless.
> > 
> > I have been tried very hard to reduce the LOC of clock-imx6q.c.  It's
> > a 5K LOC file in the Freescale internal tree.  Now it's 2K LOC.  I know
> > it's still large enough for you to dislike it.  But this is the clock
> > that the hardware has.  I'm afraid we can not do much to reduce the LOC
> > significantly, unless we only implement the small portion other than
> > the full clock tree, which is what I really hate to do.
> 
> I actually think that you have done a great job on the code and that it
> certainly looks better than a lot of the other implementations that we
> have in the tree.
> 
> Also, at least half of the code is now real driver code that we won't
> be able to reduce any further even with the clock framework. However,
> when I look at long sets of DEF_CLK and DEF_*MUX and _REGISTER_CLOCK,
> it feels like exactly the stuff that we should be moving into the
> device tree and have automatically parsed.
> 
> 	Arnd
> 

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-08  6:48         ` Shawn Guo
  2011-09-11  2:28           ` Barry Song
@ 2011-09-12 19:16           ` Grant Likely
  1 sibling, 0 replies; 69+ messages in thread
From: Grant Likely @ 2011-09-12 19:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2011 at 02:48:35PM +0800, Shawn Guo wrote:
> On Wed, Sep 07, 2011 at 08:43:06PM +0800, Barry Song wrote:
> > auxdata is really a temp solution, it really brings many details to
> > kernel, which should not be in kernel at all.
> > 
> The auxdata was originally designed to be a temp solution.  But we
> will see if it's really temp, considering it could also be used to
> carry platform callbacks and attach device id.  There are some other
> cases beside clock lookup that we have not been able to sort out just
> by device tree and will probably have to use auxdata as well.

auxdata is indeed intended to be a temporary solution, and it is an
absolute requirement that board ports migrate away from it as soon as
feasible (ie. when needed infrastructure for clk, etc, become
available).

However, I don't expect auxdata to ever be completely removed.  There
will always be a handful of boards that require something special to
be provided by board code.  In those cases, auxdata is a perfectly
acceptable solution.

g.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 16:12         ` Shawn Guo
@ 2011-09-12 19:40           ` Grant Likely
  2011-09-12 20:28             ` Arnd Bergmann
  2011-09-13  0:07             ` Shawn Guo
  0 siblings, 2 replies; 69+ messages in thread
From: Grant Likely @ 2011-09-12 19:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 13, 2011 at 12:12:02AM +0800, Shawn Guo wrote:
> On Wed, Sep 07, 2011 at 09:56:21AM +0200, Arnd Bergmann wrote:
> > On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:
> > > > My feeling is that this time, we should wait for the common clock
> > > > framework to get in and simplify this. I believe Thomas is now planning
> > > > to do this, but I haven't followed what the current state is.
> > > > 
> > > Sadly, if this is the position of entire arm-soc maintainer group,
> > > I think I have made a wrong decision to start upstreaming imx6q now.
> > 
> > We haven't discussed it as a group, it's my own opinion.
> > 
> 
> Hi Thomas, Grant,
> 
> Could you please share your opinion here?
> 
> I really do not see the hope that clock framework and device tree
> binding could possibly catch v3.2 window, while I'm hoping that imx6q
> series can go into v3.2.
> 
> Can you please agree that we can let the imx6q clock code in and then
> migrate it to clock framework and device tree once they get ready?

I've not looked very deeply at this patch, but I completely agree that
we cannot block new platforms on infrastructure that isn't remotely
mergable at this point in time.

However, imx6 is a new platform.  There isn't any non-DT board support
code to continue to support.  At the very least, the configurable
parameters, like what is passed into mx6q_clocks_init() should be
obtained from the device tree (maybe it already does this though, I
haven't looked that closely).

In general, I say merge it.

g.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 19:40           ` Grant Likely
@ 2011-09-12 20:28             ` Arnd Bergmann
  2011-09-12 21:04               ` Grant Likely
  2011-09-13  0:07             ` Shawn Guo
  1 sibling, 1 reply; 69+ messages in thread
From: Arnd Bergmann @ 2011-09-12 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 12 September 2011 13:40:33 Grant Likely wrote:
> On Tue, Sep 13, 2011 at 12:12:02AM +0800, Shawn Guo wrote:
> > On Wed, Sep 07, 2011 at 09:56:21AM +0200, Arnd Bergmann wrote:
> > > On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:
> > > > > My feeling is that this time, we should wait for the common clock
> > > > > framework to get in and simplify this. I believe Thomas is now planning
> > > > > to do this, but I haven't followed what the current state is.
> > > > > 
> > > > Sadly, if this is the position of entire arm-soc maintainer group,
> > > > I think I have made a wrong decision to start upstreaming imx6q now.
> > > 
> > > We haven't discussed it as a group, it's my own opinion.
> > > 
> > 
> > Hi Thomas, Grant,
> > 
> > Could you please share your opinion here?
> > 
> > I really do not see the hope that clock framework and device tree
> > binding could possibly catch v3.2 window, while I'm hoping that imx6q
> > series can go into v3.2.
> > 
> > Can you please agree that we can let the imx6q clock code in and then
> > migrate it to clock framework and device tree once they get ready?
> 
> I've not looked very deeply at this patch, but I completely agree that
> we cannot block new platforms on infrastructure that isn't remotely
> mergable at this point in time.
> 
> However, imx6 is a new platform.  There isn't any non-DT board support
> code to continue to support.  At the very least, the configurable
> parameters, like what is passed into mx6q_clocks_init() should be
> obtained from the device tree (maybe it already does this though, I
> haven't looked that closely).
> 
> In general, I say merge it.

Ok, thanks for taking a look. Do you believe that the clock binding is any
closer to being finalized than the actual code implementing it? I think
it would be very helpful to at least put all the clock related settings
into the device tree in a way that is going to be stable, even if the
code is still in flux.

Moreover, if we have a binding document, we can start implementing code
for one platform and then generalize it later.

	Arnd

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 20:28             ` Arnd Bergmann
@ 2011-09-12 21:04               ` Grant Likely
  0 siblings, 0 replies; 69+ messages in thread
From: Grant Likely @ 2011-09-12 21:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 10:28:27PM +0200, Arnd Bergmann wrote:
> On Monday 12 September 2011 13:40:33 Grant Likely wrote:
> > On Tue, Sep 13, 2011 at 12:12:02AM +0800, Shawn Guo wrote:
> > > On Wed, Sep 07, 2011 at 09:56:21AM +0200, Arnd Bergmann wrote:
> > > > On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:
> > > > > > My feeling is that this time, we should wait for the common clock
> > > > > > framework to get in and simplify this. I believe Thomas is now planning
> > > > > > to do this, but I haven't followed what the current state is.
> > > > > > 
> > > > > Sadly, if this is the position of entire arm-soc maintainer group,
> > > > > I think I have made a wrong decision to start upstreaming imx6q now.
> > > > 
> > > > We haven't discussed it as a group, it's my own opinion.
> > > > 
> > > 
> > > Hi Thomas, Grant,
> > > 
> > > Could you please share your opinion here?
> > > 
> > > I really do not see the hope that clock framework and device tree
> > > binding could possibly catch v3.2 window, while I'm hoping that imx6q
> > > series can go into v3.2.
> > > 
> > > Can you please agree that we can let the imx6q clock code in and then
> > > migrate it to clock framework and device tree once they get ready?
> > 
> > I've not looked very deeply at this patch, but I completely agree that
> > we cannot block new platforms on infrastructure that isn't remotely
> > mergable at this point in time.
> > 
> > However, imx6 is a new platform.  There isn't any non-DT board support
> > code to continue to support.  At the very least, the configurable
> > parameters, like what is passed into mx6q_clocks_init() should be
> > obtained from the device tree (maybe it already does this though, I
> > haven't looked that closely).
> > 
> > In general, I say merge it.
> 
> Ok, thanks for taking a look. Do you believe that the clock binding is any
> closer to being finalized than the actual code implementing it? I think

Amit is assigning a Linaro engineer to look at it, and there will be a
conference call later this week to look over the work that has been
done with an eye to getting something ready to be merged.  Hopefully
with a full time engineer things will start moving forward again.  We
had a meeting about it at LPC last week.

> it would be very helpful to at least put all the clock related settings
> into the device tree in a way that is going to be stable, even if the
> code is still in flux.
> 
> Moreover, if we have a binding document, we can start implementing code
> for one platform and then generalize it later.

Yes, a binding would be useful, but I still expect that things will be
in flux during these early stages, so there will be some room to
modify insufficient early bindings.

g.

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 19:40           ` Grant Likely
  2011-09-12 20:28             ` Arnd Bergmann
@ 2011-09-13  0:07             ` Shawn Guo
  1 sibling, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-13  0:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 01:40:33PM -0600, Grant Likely wrote:
> On Tue, Sep 13, 2011 at 12:12:02AM +0800, Shawn Guo wrote:
> > On Wed, Sep 07, 2011 at 09:56:21AM +0200, Arnd Bergmann wrote:
> > > On Wednesday 07 September 2011 14:05:03 Shawn Guo wrote:
> > > > > My feeling is that this time, we should wait for the common clock
> > > > > framework to get in and simplify this. I believe Thomas is now planning
> > > > > to do this, but I haven't followed what the current state is.
> > > > > 
> > > > Sadly, if this is the position of entire arm-soc maintainer group,
> > > > I think I have made a wrong decision to start upstreaming imx6q now.
> > > 
> > > We haven't discussed it as a group, it's my own opinion.
> > > 
> > 
> > Hi Thomas, Grant,
> > 
> > Could you please share your opinion here?
> > 
> > I really do not see the hope that clock framework and device tree
> > binding could possibly catch v3.2 window, while I'm hoping that imx6q
> > series can go into v3.2.
> > 
> > Can you please agree that we can let the imx6q clock code in and then
> > migrate it to clock framework and device tree once they get ready?
> 
> I've not looked very deeply at this patch, but I completely agree that
> we cannot block new platforms on infrastructure that isn't remotely
> mergable at this point in time.
> 
> However, imx6 is a new platform.  There isn't any non-DT board support
> code to continue to support.  At the very least, the configurable
> parameters, like what is passed into mx6q_clocks_init() should be
> obtained from the device tree (maybe it already does this though, I
> haven't looked that closely).
> 
Ok, will do in the next post.

> In general, I say merge it.
> 
Thanks, Grant.

-- 
Regards,
Shawn

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-06 20:25   ` Uwe Kleine-König
  2011-09-07 11:00     ` Shawn Guo
@ 2011-09-15  1:24     ` Shawn Guo
  1 sibling, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-15  1:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On Tue, Sep 06, 2011 at 10:25:55PM +0200, Uwe Kleine-K?nig wrote:
> On Tue, Sep 06, 2011 at 05:58:36PM +0800, Shawn Guo wrote:

[...]

> > diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > index 066d464..341f800 100644
> > --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> > +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> > @@ -1,6 +1,6 @@
> >  /*
> >   *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> > - *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> > + *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
> >   */
> >  
> >  /*
> > @@ -11,6 +11,17 @@
> >  
> >  #include <mach/hardware.h>
> >  
> > +#ifdef CONFIG_ARM_GIC
> > +#include <asm/hardware/entry-macro-gic.S>
> > +
> > +	.macro	disable_fiq
> > +	.endm
> > +
> > +	.macro	arch_ret_to_user, tmp1, tmp2
> > +	.endm
> > +
> > +#else
> > +
> hmm, this essentially means mx6 support cannot go into a kernel image
> for the other imx machines :-(
> 
I thought you gave this comment because imx6q change breaks the existing
support for single image.  But looking at the code a little bit closer,
I found that even the coexisting of AVIC and TZIC have not been
supported.  That said imx6q change did not make the situation any worse,
and we should come up with a solution later than this series to build
AVIC, TZIC and GIC in single image.

-- 
Regards,
Shawn

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

* [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src
  2011-09-12 14:27           ` Shawn Guo
@ 2011-09-15  1:26             ` Shawn Guo
  0 siblings, 0 replies; 69+ messages in thread
From: Shawn Guo @ 2011-09-15  1:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 10:27:38PM +0800, Shawn Guo wrote:
> On Mon, Sep 12, 2011 at 02:40:35PM +0200, Arnd Bergmann wrote:
> > On Monday 12 September 2011, Uwe Kleine-K?nig wrote:
> > > On Mon, Sep 12, 2011 at 07:49:33PM +0800, Shawn Guo wrote:
> > > > On Mon, Sep 12, 2011 at 11:46:34AM +0200, Sascha Hauer wrote:
> > > > > On Tue, Sep 06, 2011 at 05:58:37PM +0800, Shawn Guo wrote:
> > > > > > +static int __init imx_src_init(void)
> > > > > > +{
> > > > > > + struct device_node *np;
> > > > > > +
> > > > > > + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
> > > > > > + src_base = of_iomap(np, 0);
> > > > > > + WARN_ON(!src_base);
> > > > > > +
> > > > > > + return 0;
> > > > > > +}
> > > > > > +early_initcall(imx_src_init);
> > > > > 
> > > > > What I'm concerned about is that we carefully removed all assumptions
> > > > > about which SoC the code runs on in the past. Now with this patchset
> > > > > many of them come back. Here we have a initcall without any check
> > > > > whether we really run on i.MX6.
> > > > 
> > > > The "check" has been done on Kconfig level as below.
> > > > 
> > > > config SOC_IMX6Q
> > > >         bool "i.MX6 Quad support"
> > > >         select HAVE_IMX_SRC
> > > > 
> > > > obj-$(CONFIG_HAVE_IMX_SRC) += src.o
> > > Think multi-SoC-kernel that has SOC_IMX6Q and say SOC_IMX51.
> > 
> Aha, I did miss the point.  I was misled by "Now with this patchset
> many of them come back".  SRC is the only one being called by initcall.
> MMDC is a real platform driver.  GPC and Clock init are called by
> specific platform code.
> 
> > I think the code is almost ok, since it's only active when there is
> > a "fsl,imx6q-src" device node. However, the WARN_ON must be removed
> > if we want this to work well on a multi-soc kernel.
> > 
> > The more important point is to ensure that src_base is not being used
> > on other SoCs, but that's probably covered as well.
> > 
> Thanks, Arnd.
> 
I will drop the initcall from imx_src_init() and find some place in
imx6q platform code to call it.

-- 
Regards,
Shawn

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

* [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart
  2011-09-12 14:14         ` Russell King - ARM Linux
@ 2011-09-17 11:59           ` Russell King - ARM Linux
  0 siblings, 0 replies; 69+ messages in thread
From: Russell King - ARM Linux @ 2011-09-17 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 03:14:41PM +0100, Russell King - ARM Linux wrote:
> On Mon, Sep 12, 2011 at 10:44:39AM +0200, Sascha Hauer wrote:
> > I vote to skip params_phys and initrd_phys now. Every recent bootloader
> > does not need them. As the i.MX6 is a new SoC, we have no reason to
> > handle legacy bootloaders.
> 
> Can we stop this misunderstanding right now.
> 
> It's NOT about legacy boot loaders.  It's about the bootp code which
> allows an initrd to be packaged up together with a zImage file as one
> single file.
> 
> That's used to be able to boot with an initrd on platforms which can
> only obtain one file from the boot media, and they specify where the
> parameters are expected to be (which can be solved by updating the
> code to use r2) and where to place the initrd image (which can't be
> solved as it would mean encoding memory information for every platform
> into the bootp code.)
> 
> An example of a current boot loader which requires this: Simtec's Able
> boot loader.

Here's a patch to reduce the reliance of arch/arm/boot/bootp on having
a correct initrd image location passed from the platform Makefile.boot.
It doesn't get rid of it, as it's required if the platform does not
pass a valid value in r2 to the kernel.

Note - I have a new code for a platform (of the nommu variety) which
requires this to be able to boot.  Also note that we're probably going
to have to find a way to make this work with DT too (if not then I may
be submitting this platform without DT any support.)

---
 arch/arm/boot/bootp/init.S |   34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
index 78b5080..d1cb5a9 100644
--- a/arch/arm/boot/bootp/init.S
+++ b/arch/arm/boot/bootp/init.S
@@ -16,6 +16,14 @@
  *  size immediately following the kernel, we could build this into
  *  a binary blob, and concatenate the zImage using the cat command.
  */
+
+#define ATAG_CORE 0x54410001
+#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
+
+#define ATAG_INITRD2 0x54420005
+#define ATAG_INITRD2_SIZE ((4*4) >> 2)
+
 		.section .start,#alloc,#execinstr
 		.type	_start, #function
 		.globl	_start
@@ -37,13 +45,31 @@ _start:		add	lr, pc, #-0x8		@ lr = current load addr
 						@ r8 = initrd end
 						@ r9 = param_struct address
 
+/*
+ * Check whether we were given a valid ATAG list from the boot loader.
+ * If it looks like a valid pointer, then use that rather than the
+ * hard-coded value.
+ */
+		tst	r2, #3			@ aligned
+		bne	1f
+		ldr	r10, [r2, #0]		@ get first tag size
+		teq	r10, #ATAG_CORE_SIZE
+		teqne	r10, #ATAG_CORE_SIZE_EMPTY
+		bne	1f
+		ldr	r10, [r2, #4]		@ get first tag type
+		teq	r10, r5			@ is it ATAG_CORE?
+		bne	1f
+		mov	r9, r2
+		b	taglist
+
+1:		mov	r2, r9			@ params for the kernel
 		ldr	r10, [r9, #4]		@ get first tag
 		teq	r10, r5			@ is it ATAG_CORE?
 /*
  * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
  */
 		movne	r10, #0			@ terminator
-		movne	r4, #2			@ Size of this entry (2 words)
+		movne	r4, #ATAG_CORE_SIZE_EMPTY @ Size of this entry (2 words)
 		stmneia	r9, {r4, r5, r10}	@ Size, ATAG_CORE, terminator
 
 /*
@@ -56,7 +82,7 @@ taglist:	ldr	r10, [r9, #0]		@ tag length
 		addne	r9, r9, r10, lsl #2
 		bne	taglist
 
-		mov	r5, #4			@ Size of initrd tag (4 words)
+		mov	r5, #ATAG_INITRD2_SIZE	@ Size of initrd tag (4 words)
 		stmia	r9, {r5, r6, r7, r8, r10}
 		b	kernel_start		@ call kernel
 
@@ -80,8 +106,8 @@ data:		.word	initrd_start		@ source initrd address
 		.word	initrd_phys		@ destination initrd address
 		.word	initrd_size		@ initrd size
 
-		.word	0x54410001		@ r5 = ATAG_CORE
-		.word	0x54420005		@ r6 = ATAG_INITRD2
+		.word	ATAG_CORE		@ r5
+		.word	ATAG_INITRD2		@ r6
 		.word	initrd_phys		@ r7
 		.word	initrd_size		@ r8
 		.word	params_phys		@ r9

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

end of thread, other threads:[~2011-09-17 11:59 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-06  9:58 [PATCH 0/6] add initial imx6q support Shawn Guo
2011-09-06  9:58 ` [PATCH 1/6] arm/imx6q: add device tree source Shawn Guo
2011-09-06 18:31   ` Arnd Bergmann
2011-09-07 11:16     ` Shawn Guo
2011-09-06  9:58 ` [PATCH 2/6] arm/imx6q: add core definitions and low-level debug uart Shawn Guo
2011-09-06 18:39   ` Arnd Bergmann
2011-09-07  8:50     ` Shawn Guo
2011-09-06 20:25   ` Uwe Kleine-König
2011-09-07 11:00     ` Shawn Guo
2011-09-07 12:36       ` Uwe Kleine-König
2011-09-07 14:23         ` Russell King - ARM Linux
2011-09-07 15:36           ` Nicolas Pitre
2011-09-08 14:56             ` Arnd Bergmann
2011-09-09 17:28               ` Tony Lindgren
2011-09-12  2:30         ` Shawn Guo
2011-09-12  7:41           ` Uwe Kleine-König
2011-09-12  8:43             ` Shawn Guo
2011-09-12  8:44       ` Sascha Hauer
2011-09-12 11:36         ` Shawn Guo
2011-09-12 14:14         ` Russell King - ARM Linux
2011-09-17 11:59           ` Russell King - ARM Linux
2011-09-15  1:24     ` Shawn Guo
2011-09-06  9:58 ` [PATCH 3/6] arm/imx6q: add core drivers clock, gpc, mmdc and src Shawn Guo
2011-09-06 19:14   ` Arnd Bergmann
2011-09-07  6:05     ` Shawn Guo
2011-09-07  7:56       ` Arnd Bergmann
2011-09-12 16:12         ` Shawn Guo
2011-09-12 19:40           ` Grant Likely
2011-09-12 20:28             ` Arnd Bergmann
2011-09-12 21:04               ` Grant Likely
2011-09-13  0:07             ` Shawn Guo
2011-09-07 12:43       ` Barry Song
2011-09-08  6:48         ` Shawn Guo
2011-09-11  2:28           ` Barry Song
2011-09-12 19:16           ` Grant Likely
2011-09-12  9:46   ` Sascha Hauer
2011-09-12 11:49     ` Shawn Guo
2011-09-12 12:36       ` Uwe Kleine-König
2011-09-12 12:40         ` Arnd Bergmann
2011-09-12 14:27           ` Shawn Guo
2011-09-15  1:26             ` Shawn Guo
2011-09-06  9:58 ` [PATCH 4/6] arm/imx6q: add smp and cpu hotplug support Shawn Guo
2011-09-06 18:53   ` Arnd Bergmann
2011-09-07  4:41     ` Shawn Guo
2011-09-07  5:08       ` Shilimkar, Santosh
2011-09-07  7:46         ` Shawn Guo
2011-09-06  9:58 ` [PATCH 5/6] arm/imx6q: add device tree machine support Shawn Guo
2011-09-06 18:55   ` Arnd Bergmann
2011-09-07  3:07     ` Shawn Guo
2011-09-07  7:26       ` Arnd Bergmann
2011-09-06  9:58 ` [PATCH 6/6] arm/imx6q: add suspend/resume support Shawn Guo
2011-09-06 18:56   ` Arnd Bergmann
2011-09-07 13:50   ` Barry Song
2011-09-08  6:23     ` Shawn Guo
2011-09-08  7:47       ` Russell King - ARM Linux
2011-09-08 15:22         ` Shawn Guo
2011-09-08 16:24           ` Russell King - ARM Linux
2011-09-08 17:09             ` Lorenzo Pieralisi
2011-09-09  7:40               ` Shawn Guo
2011-09-09  6:31             ` Barry Song
2011-09-09  7:32             ` Shawn Guo
2011-09-09  8:15               ` Russell King - ARM Linux
2011-09-09 10:15                 ` Shawn Guo
2011-09-09 18:47                   ` Russell King - ARM Linux
2011-09-06 18:28 ` [PATCH 0/6] add initial imx6q support Arnd Bergmann
2011-09-06 19:42   ` Uwe Kleine-König
2011-09-07  2:55     ` Shawn Guo
2011-09-07  9:39       ` Arnd Bergmann
2011-09-07  2:51   ` Shawn Guo

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