summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boot/dts/Makefile4
-rw-r--r--arch/arm/boot/dts/vf-colibri-aster.dtsi198
-rw-r--r--arch/arm/boot/dts/vf-colibri-dual-eth.dtsi91
-rw-r--r--arch/arm/boot/dts/vf-colibri-eval-v3.dtsi148
-rw-r--r--arch/arm/boot/dts/vf-colibri.dtsi190
-rw-r--r--arch/arm/boot/dts/vf500-colibri-aster.dts22
-rw-r--r--arch/arm/boot/dts/vf500-colibri-dual-eth.dts17
-rw-r--r--arch/arm/boot/dts/vf500-colibri.dtsi5
-rw-r--r--arch/arm/boot/dts/vf500.dtsi10
-rw-r--r--arch/arm/boot/dts/vf610-colibri-aster.dts17
-rw-r--r--arch/arm/boot/dts/vf610-colibri-dual-eth.dts17
-rw-r--r--arch/arm/boot/dts/vf610-colibri.dtsi111
-rw-r--r--arch/arm/boot/dts/vf610-twr.dts4
-rw-r--r--arch/arm/boot/dts/vf610.dtsi27
-rw-r--r--arch/arm/boot/dts/vfxxx.dtsi254
-rw-r--r--arch/arm/configs/colibri_vf_defconfig330
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/mach-imx/Makefile3
-rw-r--r--arch/arm/mach-imx/common.h10
-rw-r--r--arch/arm/mach-imx/mach-vf610.c8
-rw-r--r--arch/arm/mach-imx/pm-vf610.c704
-rw-r--r--arch/arm/mach-imx/suspend-vf610.S448
22 files changed, 2578 insertions, 42 deletions
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 30bbc3746130..a5738197983a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -357,7 +357,11 @@ dtb-$(CONFIG_SOC_LS1021A) += \
dtb-$(CONFIG_SOC_VF610) += \
vf500-colibri-eval-v3.dtb \
vf610-colibri-eval-v3.dtb \
+ vf500-colibri-aster.dtb \
+ vf610-colibri-aster.dtb \
vf610m4-colibri.dtb \
+ vf500-colibri-dual-eth.dtb \
+ vf610-colibri-dual-eth.dtb \
vf610-cosmic.dtb \
vf610-twr.dtb
dtb-$(CONFIG_ARCH_MXS) += \
diff --git a/arch/arm/boot/dts/vf-colibri-aster.dtsi b/arch/arm/boot/dts/vf-colibri-aster.dtsi
new file mode 100644
index 000000000000..7710d562144f
--- /dev/null
+++ b/arch/arm/boot/dts/vf-colibri-aster.dtsi
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2017 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ ethernet0 = &fec1;
+ ethernet1 = &fec0;
+ };
+
+ panel: panel {
+ compatible = "edt,et057090dhu";
+ backlight = <&bl>;
+ power-supply = <&reg_3v3>;
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio3 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* USBH_PEN resp. USBH_P_EN */
+ vin-supply = <&reg_5v0>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&bl {
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <6>;
+ power-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+&dcu0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dcu0_1>;
+ fsl,panel = <&panel>;
+ status = "okay";
+};
+
+&dspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_aster_dspi1 &pinctrl_aster_spi_gpio>;
+ status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&fec1 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ status = "disabled";
+ };
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc: m41t0m6@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&reg_module_3v3 {
+ vin-supply = <&reg_3v3>;
+};
+
+&tcon0 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usbdev0 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
+&usbh1 {
+ vbus-supply = <&reg_usbh_vbus>;
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_gpiokeys: gpiokeys {
+ fsl,pins = <
+ VF610_PAD_PTB19__GPIO_41 0x218d
+ >;
+ };
+
+ pinctrl_aster_dspi1: dspi1grp {
+ fsl,pins = <
+ VF610_PAD_PTD6__DSPI1_SIN 0x33e1
+ VF610_PAD_PTD7__DSPI1_SOUT 0x33e2
+ VF610_PAD_PTD8__DSPI1_SCK 0x33e2
+ >;
+ };
+
+ pinctrl_aster_spi_gpio: spigpios {
+ fsl,pins = <
+ /* CS0 */
+ VF610_PAD_PTD5__GPIO_84 0x22ed
+ /* CS1 */
+ VF610_PAD_PTB18__GPIO_40 0x22ed
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi b/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi
new file mode 100644
index 000000000000..8fed7304276a
--- /dev/null
+++ b/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/ {
+ chosen {
+ bootargs = "console=ttyLP0,115200";
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ ethernet0 = &fec0;
+ ethernet1 = &fec1;
+ };
+};
+
+&fec0 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec0>;
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_fec0: fec0grp {
+ fsl,pins = <
+ VF610_PAD_PTA9__RMII_CLKOUT 0x30d2
+ VF610_PAD_PTC0__ENET_RMII0_MDC 0x30d2
+ VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d3
+ VF610_PAD_PTC2__ENET_RMII0_CRS 0x30d1
+ VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1
+ VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1
+ VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1
+ VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2
+ VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2
+ VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2
+ /* Disable pads multiplexed with PTC7/PTC6 */
+ VF610_PAD_PTB0__GPIO_22 0x0000
+ VF610_PAD_PTB9__GPIO_31 0x0000
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ VF610_PAD_PTA20__UART3_TX 0x21a2
+ VF610_PAD_PTA21__UART3_RX 0x21a1
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ VF610_PAD_PTA28__UART4_TX 0x21a2
+ VF610_PAD_PTA29__UART4_RX 0x21a1
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index ed65e0f7dfc0..dc703043d3ac 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -7,42 +7,76 @@
* (at your option) any later version.
*/
+#include <dt-bindings/input/input.h>
+
/ {
chosen {
stdout-path = "serial0:115200n8";
};
+ aliases {
+ ethernet0 = &fec1;
+ ethernet1 = &fec0;
+ };
+
clk16m: clk16m {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <16000000>;
};
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- sys_5v0_reg: regulator@0 {
- compatible = "regulator-fixed";
- reg = <0>;
- regulator-name = "5v0";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-always-on;
- };
+ panel: panel {
+ compatible = "edt,et057090dhu";
+ backlight = <&bl>;
+ power-supply = <&reg_3v3>;
+ };
+
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ debounce = <25>;
+ id-gpio = <&gpio3 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_5v0: regulator-5v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usbh_vbus: regulator-usbh-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1_reg>;
+ regulator-name = "VCC_USB[1-4]";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* USBH_PEN resp. USBH_P_EN */
+ vin-supply = <&reg_5v0>;
+ };
- /* USBH_PEN */
- usbh_vbus_reg: regulator@1 {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbh1_reg>;
- reg = <1>;
- regulator-name = "usbh_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio2 19 GPIO_ACTIVE_LOW>;
- vin-supply = <&sys_5v0_reg>;
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
};
};
};
@@ -50,12 +84,27 @@
&bl {
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
+ power-supply = <&reg_3v3>;
status = "okay";
};
+&dcu0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dcu0_1>;
+ fsl,panel = <&panel>;
+ status = "okay";
+};
+
&dspi1 {
status = "okay";
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ };
+
mcp2515can: can@0 {
compatible = "microchip,mcp2515";
pinctrl-names = "default";
@@ -65,6 +114,7 @@
spi-max-frequency = <10000000>;
interrupt-parent = <&gpio1>;
interrupts = <11 GPIO_ACTIVE_LOW>;
+ status = "disabled";
};
};
@@ -85,9 +135,30 @@
&i2c0 {
status = "okay";
+ /* Atmel maxtouch controller */
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ status = "disabled";
+ };
+
+ /* TouchRevolution Fusion 7 and 10 multi-touch controller */
+ touch: touchrevf0710a@10 {
+ compatible = "touchrevolution,fusion-f0710a";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiotouch>;
+ reg = <0x10>;
+ gpios = <&gpio0 30 GPIO_ACTIVE_HIGH /* SO-DIMM 28, Pen down interrupt */
+ &gpio0 23 GPIO_ACTIVE_LOW /* SO-DIMM 30, Reset interrupt */
+ >;
+ status = "disabled";
+ };
+
/* M41T0M6 real time clock on carrier board */
rtc: m41t0m6@68 {
- compatible = "st,m41t00";
+ compatible = "st,m41t0";
reg = <0x68>;
};
};
@@ -100,6 +171,14 @@
status = "okay";
};
+&reg_module_3v3 {
+ vin-supply = <&reg_3v3>;
+};
+
+&tcon0 {
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
@@ -112,8 +191,12 @@
status = "okay";
};
+&usbdev0 {
+ extcon = <&extcon_usbc_det>, <&extcon_usbc_det>;
+};
+
&usbh1 {
- vbus-supply = <&usbh_vbus_reg>;
+ vbus-supply = <&reg_usbh_vbus>;
};
&iomuxc {
@@ -123,5 +206,18 @@
VF610_PAD_PTB21__GPIO_43 0x22ed
>;
};
+
+ pinctrl_gpiokeys: gpiokeys {
+ fsl,pins = <
+ VF610_PAD_PTB19__GPIO_41 0x218d
+ >;
+ };
+
+ pinctrl_gpiotouch: touchgpios {
+ fsl,pins = <
+ VF610_PAD_PTB8__GPIO_30 0x6f
+ VF610_PAD_PTB1__GPIO_23 0x4f
+ >;
+ };
};
};
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index e5949b934945..7d11341cc567 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -10,17 +10,61 @@
/ {
bl: backlight {
compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_bl_on>;
pwms = <&pwm0 0 5000000 0>;
+ enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
+
+ reg_module_3v3: regulator-module-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_module_3v3_avdd: regulator-module-3v3-avdd {
+ compatible = "regulator-fixed";
+ regulator-name = "+V3.3_AVDD_AUDIO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ soc {
+ fsl,use-lpm-poweroff;
+ };
};
&adc0 {
status = "okay";
+ vref-supply = <&reg_module_3v3_avdd>;
};
&adc1 {
status = "okay";
+ vref-supply = <&reg_module_3v3_avdd>;
+};
+
+&can0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan0>;
+ status = "disabled";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+&clks {
+ assigned-clocks = <&clks VF610_CLK_ENET_SEL>,
+ <&clks VF610_CLK_ENET_TS_SEL>;
+ assigned-clock-parents = <&clks VF610_CLK_ENET_50M>,
+ <&clks VF610_CLK_ENET_50M>;
};
&dspi1 {
@@ -33,15 +77,21 @@
status = "okay";
};
+&edma1 {
+ status = "okay";
+};
+
&esdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc1>;
bus-width = <4>;
cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ disable-wp;
};
&fec1 {
phy-mode = "rmii";
+ phy-supply = <&reg_module_3v3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
};
@@ -53,8 +103,6 @@
};
&nfc {
- assigned-clocks = <&clks VF610_CLK_NFC>;
- assigned-clock-rates = <33000000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nfc>;
status = "okay";
@@ -74,12 +122,12 @@
&pwm0 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm0>;
+ pinctrl-0 = <&pinctrl_pwm0_a &pinctrl_pwm0_c>;
};
&pwm1 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm1>;
+ pinctrl-0 = <&pinctrl_pwm1_b &pinctrl_pwm1_d>;
};
&uart0 {
@@ -99,6 +147,7 @@
&usbdev0 {
disable-over-current;
+ dr_mode = "otg";
status = "okay";
};
@@ -124,12 +173,54 @@
};
&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog_0 &pinctrl_hog_1>;
+
vf610-colibri {
- pinctrl_gpio_ext: gpio_ext {
+ pinctrl_flexcan0: can0grp {
+ fsl,pins = <
+ VF610_PAD_PTB14__CAN0_RX 0x31F1
+ VF610_PAD_PTB15__CAN0_TX 0x31F2
+ >;
+ };
+
+ pinctrl_flexcan1: can1grp {
fsl,pins = <
- VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */
- VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */
- VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */
+ VF610_PAD_PTB16__CAN1_RX 0x31F1
+ VF610_PAD_PTB17__CAN1_TX 0x31F2
+ >;
+ };
+
+ pinctrl_dcu0_1: dcu0grp_1 {
+ fsl,pins = <
+ VF610_PAD_PTE0__DCU0_HSYNC 0x1902
+ VF610_PAD_PTE1__DCU0_VSYNC 0x1902
+ VF610_PAD_PTE2__DCU0_PCLK 0x1902
+ VF610_PAD_PTE4__DCU0_DE 0x1902
+ VF610_PAD_PTE5__DCU0_R0 0x1902
+ VF610_PAD_PTE6__DCU0_R1 0x1902
+ VF610_PAD_PTE7__DCU0_R2 0x1902
+ VF610_PAD_PTE8__DCU0_R3 0x1902
+ VF610_PAD_PTE9__DCU0_R4 0x1902
+ VF610_PAD_PTE10__DCU0_R5 0x1902
+ VF610_PAD_PTE11__DCU0_R6 0x1902
+ VF610_PAD_PTE12__DCU0_R7 0x1902
+ VF610_PAD_PTE13__DCU0_G0 0x1902
+ VF610_PAD_PTE14__DCU0_G1 0x1902
+ VF610_PAD_PTE15__DCU0_G2 0x1902
+ VF610_PAD_PTE16__DCU0_G3 0x1902
+ VF610_PAD_PTE17__DCU0_G4 0x1902
+ VF610_PAD_PTE18__DCU0_G5 0x1902
+ VF610_PAD_PTE19__DCU0_G6 0x1902
+ VF610_PAD_PTE20__DCU0_G7 0x1902
+ VF610_PAD_PTE21__DCU0_B0 0x1902
+ VF610_PAD_PTE22__DCU0_B1 0x1902
+ VF610_PAD_PTE23__DCU0_B2 0x1902
+ VF610_PAD_PTE24__DCU0_B3 0x1902
+ VF610_PAD_PTE25__DCU0_B4 0x1902
+ VF610_PAD_PTE26__DCU0_B5 0x1902
+ VF610_PAD_PTE27__DCU0_B6 0x1902
+ VF610_PAD_PTE28__DCU0_B7 0x1902
>;
};
@@ -169,6 +260,67 @@
>;
};
+ pinctrl_gpio_bl_on: gpio_bl_on {
+ fsl,pins = <
+ VF610_PAD_PTC0__GPIO_45 0x22ef
+ >;
+ };
+
+ pinctrl_hog_0: hoggrp-0 {
+ fsl,pins = <
+ VF610_PAD_PTA12__GPIO_5 0x22ed
+ VF610_PAD_PTA17__GPIO_7 0x22ed
+ VF610_PAD_PTA20__GPIO_10 0x22ed
+ VF610_PAD_PTA21__GPIO_11 0x22ed
+ VF610_PAD_PTA30__GPIO_20 0x22ed
+ VF610_PAD_PTA31__GPIO_21 0x22ed
+ VF610_PAD_PTB6__GPIO_28 0x22ed
+ VF610_PAD_PTB7__GPIO_29 0x22ed
+ VF610_PAD_PTB16__GPIO_38 0x22ed
+ VF610_PAD_PTB17__GPIO_39 0x22ed
+ VF610_PAD_PTB18__GPIO_40 0x22ed
+ VF610_PAD_PTB21__GPIO_43 0x22ed
+ VF610_PAD_PTB22__GPIO_44 0x22ed
+ VF610_PAD_PTC1__GPIO_46 0x22ed
+ VF610_PAD_PTC2__GPIO_47 0x22ed
+ VF610_PAD_PTC3__GPIO_48 0x22ed
+ VF610_PAD_PTC4__GPIO_49 0x22ed
+ VF610_PAD_PTC5__GPIO_50 0x22ed
+ VF610_PAD_PTC6__GPIO_51 0x22ed
+ VF610_PAD_PTC7__GPIO_52 0x22ed
+ VF610_PAD_PTC8__GPIO_53 0x22ed
+ VF610_PAD_PTD30__GPIO_64 0x22ed
+ VF610_PAD_PTD29__GPIO_65 0x22ed
+ VF610_PAD_PTD28__GPIO_66 0x22ed
+ VF610_PAD_PTD26__GPIO_68 0x22ed
+ VF610_PAD_PTD25__GPIO_69 0x22ed
+ VF610_PAD_PTD24__GPIO_70 0x22ed
+ VF610_PAD_PTD9__GPIO_88 0x22ed
+ VF610_PAD_PTD10__GPIO_89 0x22ed
+ VF610_PAD_PTD11__GPIO_90 0x22ed
+ VF610_PAD_PTD12__GPIO_91 0x22ed
+ VF610_PAD_PTD13__GPIO_92 0x22ed
+ VF610_PAD_PTB26__GPIO_96 0x22ed
+ VF610_PAD_PTB28__GPIO_98 0x22ed
+ VF610_PAD_PTC30__GPIO_103 0x22ed
+ VF610_PAD_PTA7__GPIO_134 0x22ed
+ >;
+ };
+
+ pinctrl_hog_1: hoggrp-1 { /* ATMEL MXT TOUCH */
+ fsl,pins = <
+ VF610_PAD_PTD27__GPIO_67 0x22ed
+ VF610_PAD_PTD31__GPIO_63 0x22ed
+ >;
+ };
+
+ pinctrl_hog_2: hoggrp-2 {
+ fsl,pins = <
+ VF610_PAD_PTB12__GPIO_34 0x22ed
+ VF610_PAD_PTB13__GPIO_35 0x22ed
+ >;
+ };
+
pinctrl_i2c0: i2c0grp {
fsl,pins = <
VF610_PAD_PTB14__I2C0_SCL 0x37ff
@@ -195,16 +347,26 @@
>;
};
- pinctrl_pwm0: pwm0grp {
+ pinctrl_pwm0_a: pwm0agrp {
fsl,pins = <
VF610_PAD_PTB0__FTM0_CH0 0x1182
+ >;
+ };
+
+ pinctrl_pwm0_c: pwm0cgrp {
+ fsl,pins = <
VF610_PAD_PTB1__FTM0_CH1 0x1182
>;
};
- pinctrl_pwm1: pwm1grp {
+ pinctrl_pwm1_b: pwm1bgrp {
fsl,pins = <
VF610_PAD_PTB8__FTM1_CH0 0x1182
+ >;
+ };
+
+ pinctrl_pwm1_d: pwm1dgrp {
+ fsl,pins = <
VF610_PAD_PTB9__FTM1_CH1 0x1182
>;
};
@@ -213,6 +375,8 @@
fsl,pins = <
VF610_PAD_PTB10__UART0_TX 0x21a2
VF610_PAD_PTB11__UART0_RX 0x21a1
+ VF610_PAD_PTB12__UART0_RTS 0x21a2
+ VF610_PAD_PTB13__UART0_CTS 0x21a1
>;
};
@@ -232,6 +396,12 @@
>;
};
+ pinctrl_usbc_det: gpio_usbc_det {
+ fsl,pins = <
+ VF610_PAD_PTC29__GPIO_102 0x22cd
+ >;
+ };
+
pinctrl_usbh1_reg: gpio_usb_vbus {
fsl,pins = <
VF610_PAD_PTD4__GPIO_83 0x22ed
diff --git a/arch/arm/boot/dts/vf500-colibri-aster.dts b/arch/arm/boot/dts/vf500-colibri-aster.dts
new file mode 100644
index 000000000000..e314a7ab67ae
--- /dev/null
+++ b/arch/arm/boot/dts/vf500-colibri-aster.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf500-colibri.dtsi"
+#include "vf-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri VF50 on Colibri Aster Board";
+ compatible = "toradex,vf500-colibri_vf50-on-aster", "toradex,vf500-colibri_vf50", "fsl,vf500";
+};
+
+&touchscreen {
+ vf50-ts-min-pressure = <200>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri-dual-eth.dts b/arch/arm/boot/dts/vf500-colibri-dual-eth.dts
new file mode 100644
index 000000000000..24990e241e0e
--- /dev/null
+++ b/arch/arm/boot/dts/vf500-colibri-dual-eth.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf500-colibri.dtsi"
+#include "vf-colibri-dual-eth.dtsi"
+
+/ {
+ model = "Toradex Colibri VF50 on Dual Ethernet Board";
+ compatible = "toradex,vf500-colibri_vf50-on-dual-eth-board", "toradex,vf500-colibri_vf50", "fsl,vf500";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
index 84f091d1fcf2..731ff0091c9d 100644
--- a/arch/arm/boot/dts/vf500-colibri.dtsi
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -37,6 +37,11 @@
};
};
+&nfc {
+ assigned-clocks = <&clks VF610_CLK_NFC>;
+ assigned-clock-rates = <33000000>;
+};
+
&iomuxc {
vf610-colibri {
pinctrl_touchctrl_idle: touchctrl_idle {
diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi
index e976d2fa1527..f2be079aae51 100644
--- a/arch/arm/boot/dts/vf500.dtsi
+++ b/arch/arm/boot/dts/vf500.dtsi
@@ -43,6 +43,16 @@
clocks = <&clks VF610_CLK_PLATFORM_BUS>;
};
};
+
+ aips-bus@40080000 {
+
+ pmu@40089000 {
+ compatible = "arm,cortex-a5-pmu";
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&a5_cpu>;
+ };
+ };
+
};
};
diff --git a/arch/arm/boot/dts/vf610-colibri-aster.dts b/arch/arm/boot/dts/vf610-colibri-aster.dts
new file mode 100644
index 000000000000..55efc161001e
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-colibri-aster.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2017 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610-colibri.dtsi"
+#include "vf-colibri-aster.dtsi"
+
+/ {
+ model = "Toradex Colibri VF61 on Colibri Aster Board";
+ compatible = "toradex,vf610-colibri_vf61-on-aster", "toradex,vf610-colibri_vf61", "fsl,vf610";
+};
diff --git a/arch/arm/boot/dts/vf610-colibri-dual-eth.dts b/arch/arm/boot/dts/vf610-colibri-dual-eth.dts
new file mode 100644
index 000000000000..a2eff553956c
--- /dev/null
+++ b/arch/arm/boot/dts/vf610-colibri-dual-eth.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Toradex AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610-colibri.dtsi"
+#include "vf-colibri-dual-eth.dtsi"
+
+/ {
+ model = "Toradex Colibri VF61 on Dual Ethernet Board";
+ compatible = "toradex,vf610-colibri_vf61-on-dual-eth-board", "toradex,vf610-colibri_vf61", "fsl,vf610";
+};
diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi
index 2d7eab755210..a8d59f7bef06 100644
--- a/arch/arm/boot/dts/vf610-colibri.dtsi
+++ b/arch/arm/boot/dts/vf610-colibri.dtsi
@@ -17,4 +17,115 @@
memory {
reg = <0x80000000 0x10000000>;
};
+
+ sound {
+ compatible = "fsl,fsl-sai-audio-wm9712";
+ fsl,ac97-controller = <&sai2>;
+
+ fsl,model = "Colibri VF61 AC97 Audio";
+
+ fsl,audio-routing =
+ "Headphone", "HPOUTL",
+ "Headphone", "HPOUTR",
+ "LINEINL", "LineIn",
+ "LINEINR", "LineIn",
+ "MIC1", "Mic";
+ };
+};
+
+&nfc {
+ assigned-clocks = <&clks VF610_CLK_NFC>;
+ assigned-clock-rates = <50000000>;
+};
+
+&sai0 {
+ compatible = "fsl,vf610-sai-clk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai0>;
+ status = "okay";
+};
+
+&sai2 {
+ compatible = "fsl,vf610-sai-ac97";
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default", "sleep", "ac97-running", "ac97-reset",
+ "ac97-warm-reset";
+ pinctrl-0 = <&pinctrl_sai2_ac97_default>;
+ pinctrl-1 = <&pinctrl_sai2_ac97_sleep>;
+ pinctrl-2 = <&pinctrl_sai2_ac97_running>;
+ pinctrl-3 = <&pinctrl_sai2_ac97_reset>;
+ pinctrl-4 = <&pinctrl_sai2_ac97_warm_reset>;
+ ac97-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH &gpio0 8 GPIO_ACTIVE_HIGH
+ &gpio0 13 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&iomuxc {
+ vf610-colibri {
+ pinctrl_sai0: sai0grp_1 {
+ fsl,pins = <
+ VF610_PAD_PTB23__SAI0_TX_BCLK 0x31C3
+ >;
+ };
+
+ pinctrl_sai2_ac97_default: sai2grp_1 {
+ fsl,pins = <
+ /* Pen-down */
+ VF610_PAD_PTA11__GPIO_4 0x22ed
+
+ /* GenIRQ */
+ VF610_PAD_PTB2__GPIO_24 0x22e1
+ >;
+ };
+
+ pinctrl_sai2_ac97_sleep: sai2grp_2 {
+ fsl,pins = <
+ /* AC97 Reset (cold reset) floating */
+ VF610_PAD_PTA23__GPIO_13 0x22c1
+ >;
+ };
+
+ pinctrl_sai2_ac97_running: sai2grp_3 {
+ fsl,pins = <
+ /* AC97 Bit clock */
+ VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C3
+
+ /* AC97 SData Out */
+ VF610_PAD_PTA18__SAI2_TX_DATA 0x31C2
+
+ /* AC97 Sync */
+ VF610_PAD_PTA19__SAI2_TX_SYNC 0x31C3
+
+ /* AC97 SData In */
+ VF610_PAD_PTA22__SAI2_RX_DATA 0x0041
+ >;
+ };
+
+ pinctrl_sai2_ac97_reset: sai2grp_4 {
+ fsl,pins = <
+ VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C1
+
+ /* AC97 SData Out (test mode selection) */
+ VF610_PAD_PTA18__GPIO_8 0x22c1
+
+ /* AC97 Sync (warm reset) */
+ VF610_PAD_PTA19__GPIO_9 0x22c1
+
+ /* AC97 Reset (cold reset) */
+ VF610_PAD_PTA23__GPIO_13 0x22c1
+ >;
+ };
+
+ pinctrl_sai2_ac97_warm_reset: sai2grp_5 {
+ fsl,pins = <
+ /* AC97 SData Out (test mode selection) */
+ VF610_PAD_PTA18__GPIO_8 0x22c1
+
+ /* AC97 Sync (warm reset) */
+ VF610_PAD_PTA19__GPIO_9 0x22c1
+ >;
+ };
+
+
+ };
};
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 5438ee4be2ec..8419c0607f9b 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -96,6 +96,10 @@
&clks {
clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>;
clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext";
+ assigned-clocks = <&clks VF610_CLK_ENET_SEL>,
+ <&clks VF610_CLK_ENET_TS_SEL>;
+ assigned-clock-parents = <&clks VF610_CLK_ENET_EXT>,
+ <&clks VF610_CLK_ENET_EXT>;
};
&dspi0 {
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 58bc6e448be5..f731b598e2c5 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -22,4 +22,31 @@
arm,data-latency = <3 3 3>;
arm,tag-latency = <2 2 2>;
};
+
+ sema4: sema4@4001D000 {
+ compatible = "fsl,vf610-sema4";
+ reg = <0x4001D000 0x1000>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ CM4: cortexm4 {
+ compatible = "simple-bus";
+ ranges = <0x1f000000 0x3f000000 0x80000
+ 0x3f000000 0x3f000000 0x80000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cortexm4core {
+ compatible = "fsl,vf610-m4";
+ reg = <0x1f000000 0x80000>,
+ <0x3f000000 0x80000>;
+ reg-names = "pc_ocram", "ps_ocram";
+ fsl,firmware = "freertos-rpmsg.elf";
+ };
+ };
+
+ rpmsg: rpmsg {
+ compatible = "fsl,vf610-rpmsg";
+ status = "okay";
+ };
};
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 3cd1b27f2697..bf4e8048fac8 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -16,6 +16,8 @@
aliases {
can0 = &can0;
can1 = &can1;
+ ethernet0 = &fec0;
+ ethernet1 = &fec1;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
@@ -53,9 +55,56 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "simple-bus";
- interrupt-parent = <&mscm_ir>;
+ compatible = "fsl,vf610-soc-bus", "simple-bus";
+ interrupt-parent = <&gpc>;
ranges;
+ fsl,rom-revision = <&ocrom 0x80>;
+ fsl,cpu-count = <&mscm_cpucfg 0x2C>;
+ fsl,l2-size = <&mscm_cpucfg 0x14>;
+ nvmem-cells = <&ocotp_cfg0>, <&ocotp_cfg1>;
+ nvmem-cell-names = "cfg0", "cfg1";
+
+ ocrom: ocrom@00000000 {
+ compatible = "fsl,vf610-ocrom", "syscon";
+ reg = <0x00000000 0x18000>;
+ };
+
+ ocram0: sram@3f000000 {
+ compatible = "mmio-sram";
+ reg = <0x3f000000 0x40000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x3f000000 0x40000>;
+
+ stbyram1@0 {
+ reg = <0x0 0x4000>;
+ label = "stbyram1";
+ pool;
+ };
+
+ stbyram2@4000 {
+ reg = <0x4000 0xc000>;
+ label = "stbyram2";
+ pool;
+ };
+ };
+
+ ocram1: sram@3f040000 {
+ compatible = "mmio-sram";
+ reg = <0x3f040000 0x40000>;
+ };
+
+ gfxram0: sram@3f400000 {
+ compatible = "mmio-sram";
+ reg = <0x3f400000 0x80000>;
+ };
+
+ /* used by L2 cache */
+ gfxram1: sram@3f480000 {
+ compatible = "mmio-sram";
+ reg = <0x3f480000 0x80000>;
+ };
aips0: aips-bus@40000000 {
compatible = "fsl,aips-bus", "simple-bus";
@@ -70,10 +119,22 @@
mscm_ir: interrupt-controller@40001800 {
compatible = "fsl,vf610-mscm-ir";
+ #address-cells = <1>;
+ #size-cells = <1>;
reg = <0x40001800 0x400>;
fsl,cpucfg = <&mscm_cpucfg>;
interrupt-controller;
#interrupt-cells = <2>;
+
+ cpu2cpu@40001800 {
+ reg = <0x40001800 0x40>;
+ interrupt-parent = <&mscm_ir>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>,
+ <1 IRQ_TYPE_LEVEL_HIGH>,
+ <2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1", "int2", "int3";
+ };
};
edma0: dma-controller@40018000 {
@@ -159,6 +220,9 @@
clocks = <&clks VF610_CLK_DSPI0>;
clock-names = "dspi";
spi-num-chipselects = <6>;
+ dmas = <&edma1 1 12>,
+ <&edma1 1 13>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -171,6 +235,37 @@
clocks = <&clks VF610_CLK_DSPI1>;
clock-names = "dspi";
spi-num-chipselects = <4>;
+ dmas = <&edma1 1 14>,
+ <&edma1 1 15>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ sai0: sai@4002f000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x4002f000 0x1000>;
+ interrupts = <84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_SAI0>,
+ <&clks VF610_CLK_SAI0_DIV>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 0 17>,
+ <&edma0 0 16>;
+ status = "disabled";
+ };
+
+ sai1: sai@40030000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x40030000 0x1000>;
+ interrupts = <85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_SAI1>,
+ <&clks VF610_CLK_SAI1_DIV>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 0 19>,
+ <&edma0 0 18>;
status = "disabled";
};
@@ -188,6 +283,20 @@
status = "disabled";
};
+ sai3: sai@40032000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x40032000 0x1000>;
+ interrupts = <87 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_SAI3>,
+ <&clks VF610_CLK_SAI3_DIV>,
+ <&clks 0>, <&clks 0>;
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 1 9>,
+ <&edma0 1 8>;
+ status = "disabled";
+ };
+
pit: pit@40037000 {
compatible = "fsl,vf610-pit";
reg = <0x40037000 0x1000>;
@@ -234,6 +343,14 @@
<20000000>;
};
+ tcon0: timing-controller@4003d000 {
+ compatible = "fsl,vf610-tcon";
+ reg = <0x4003d000 0x1000>;
+ clocks = <&clks VF610_CLK_TCON0>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
wdoga5: wdog@4003e000 {
compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
@@ -270,6 +387,7 @@
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&iomuxc 0 0 32>;
+ fsl,gpio-wakeup = <&wakeup 22 0 8>; /* PTB0...PTB7 */
};
gpio1: gpio@4004a000 {
@@ -281,6 +399,10 @@
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&iomuxc 0 32 32>;
+ fsl,gpio-wakeup = <&wakeup 1 8 2>, /* PTB11, PTB12 (NMI)*/
+ <&wakeup 4 10 1>, /* PTB14 */
+ <&wakeup 6 11 1>, /* PTB16 */
+ <&wakeup 9 12 2>; /* PTB19, PTB20 */
};
gpio2: gpio@4004b000 {
@@ -303,6 +425,9 @@
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&iomuxc 0 96 32>;
+ fsl,gpio-wakeup = <&wakeup 1 14 1>, /* PTB27 */
+ <&wakeup 7 15 1>, /* PTC30 */
+ <&wakeup 29 16 1>; /* PTE20 */
};
gpio4: gpio@4004d000 {
@@ -321,6 +446,11 @@
reg = <0x40050000 0x400>;
};
+ scsc: scsc@40052000 {
+ compatible = "fsl,vf610-scsc";
+ reg = <0x40052000 0x1000>;
+ };
+
usbphy0: usbphy@40050800 {
compatible = "fsl,vf610-usbphy";
reg = <0x40050800 0x400>;
@@ -339,6 +469,17 @@
status = "disabled";
};
+ dcu0: dcu@40058000 {
+ compatible = "fsl,vf610-dcu";
+ reg = <0x40058000 0x1200>;
+ interrupts = <30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DCU0>,
+ <&clks VF610_CLK_DCU0_DIV>;
+ clock-names = "dcu", "pix";
+ fsl,tcon = <&tcon0>;
+ status = "disabled";
+ };
+
i2c0: i2c@40066000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -367,8 +508,15 @@
status = "disabled";
};
+ wakeup: wkpu@4006a000 {
+ compatible = "fsl,vf610-wkpu";
+ reg = <0x4006a000 0x1000>;
+ interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_WKPU>;
+ };
+
clks: ccm@4006b000 {
- compatible = "fsl,vf610-ccm";
+ compatible = "fsl,vf610-ccm", "syscon";
reg = <0x4006b000 0x1000>;
clocks = <&sxosc>, <&fxosc>;
clock-names = "sxosc", "fxosc";
@@ -376,7 +524,7 @@
};
usbdev0: usb@40034000 {
- compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+ compatible = "fsl,vf610-usb";
reg = <0x40034000 0x800>;
interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_USBC0>;
@@ -399,6 +547,14 @@
reg = <0x4006e000 0x1000>;
interrupts = <96 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ gpc: gpc@4006c000 {
+ compatible = "fsl,vf610-gpc";
+ reg = <0x4006c000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&mscm_ir>;
+ };
};
aips1: aips-bus@40080000 {
@@ -423,6 +579,22 @@
status = "disabled";
};
+ ocotp@400a5000 {
+ compatible = "fsl,vf610-ocotp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x400a5000 0xCF0>;
+ clocks = <&clks VF610_CLK_OCOTP>;
+
+ ocotp_cfg0: cfg0@410 {
+ reg = <0x410 0x4>;
+ };
+
+ ocotp_cfg1: cfg1@420 {
+ reg = <0x420 0x4>;
+ };
+ };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x400a7000 0x2000>;
@@ -455,6 +627,43 @@
status = "disabled";
};
+ dspi2: dspi2@400ac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x400ac000 0x1000>;
+ interrupts = <69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI2>;
+ clock-names = "dspi";
+ spi-num-chipselects = <2>;
+ dmas = <&edma1 0 10>,
+ <&edma1 0 11>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ dspi3: dspi3@400ad000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,vf610-dspi";
+ reg = <0x400ad000 0x1000>;
+ interrupts = <70 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_DSPI3>;
+ clock-names = "dspi";
+ spi-num-chipselects = <2>;
+ dmas = <&edma1 0 12>,
+ <&edma1 0 13>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ ddrmc: ddrmc@400ae000 {
+ compatible = "fsl,vf610-ddrmc";
+ reg = <0x400ae000 0x400>;
+ clocks = <&clks VF610_CLK_DDRMC>;
+ clock-names = "ddrc";
+ };
+
adc1: adc@400bb000 {
compatible = "fsl,vf610-adc";
reg = <0x400bb000 0x1000>;
@@ -490,7 +699,7 @@
};
usbh1: usb@400b4000 {
- compatible = "fsl,vf610-usb", "fsl,imx27-usb";
+ compatible = "fsl,vf610-usb";
reg = <0x400b4000 0x800>;
interrupts = <76 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_USBC1>;
@@ -534,6 +743,24 @@
status = "disabled";
};
+ dac0: dac@400cc000 {
+ compatible = "fsl,vf610-dac";
+ reg = <0x400cc000 1000>;
+ interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dac";
+ clocks = <&clks VF610_CLK_DAC0>;
+ status = "disabled";
+ };
+
+ dac1: dac@400cd000 {
+ compatible = "fsl,vf610-dac";
+ reg = <0x400cd000 1000>;
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dac";
+ clocks = <&clks VF610_CLK_DAC1>;
+ status = "disabled";
+ };
+
fec0: ethernet@400d0000 {
compatible = "fsl,mvf600-fec";
reg = <0x400d0000 0x1000>;
@@ -577,6 +804,18 @@
status = "disabled";
};
+ esw: l2-switch@400e8000 {
+ compatible = "fsl,eth-switch";
+ reg = <0x400e8000 0x1000 0x400d0000 0x2000>;
+ interrupts = <82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks VF610_CLK_ESW>,
+ <&clks VF610_CLK_ENET>,
+ <&clks VF610_CLK_ENET0>,
+ <&clks VF610_CLK_ENET1>;
+ clock-names = "esw", "enet", "enet0", "enet1";
+ status = "disabled";
+ };
+
i2c2: i2c@400e6000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -605,5 +844,10 @@
status = "disabled";
};
};
+
+ adc_hwmon: iio_hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 16>, <&adc1 16>;
+ };
};
};
diff --git a/arch/arm/configs/colibri_vf_defconfig b/arch/arm/configs/colibri_vf_defconfig
new file mode 100644
index 000000000000..4f58b80eaaf1
--- /dev/null
+++ b/arch/arm/configs/colibri_vf_defconfig
@@ -0,0 +1,330 @@
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CGROUPS=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_VF610=y
+CONFIG_SWP_EMULATE=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_CMA=y
+CONFIG_KEXEC=y
+# CONFIG_ATAGS_PROC is not set
+CONFIG_CPU_IDLE=y
+# CONFIG_CPU_IDLE_GOV_LADDER is not set
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE_DEMUX=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6_SIT=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_MASQ=y
+CONFIG_NFT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NFT_CHAIN_NAT_IPV4=y
+CONFIG_NFT_MASQ_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_L2TP=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_CAN=m
+CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251X=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_DMA_CMA=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VF610_NFC=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+CONFIG_FSL_L2_SWITCH=y
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MICREL_PHY=y
+CONFIG_PPP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_NET_DRIVERS=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_NCM is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_FUSION_F0710A=m
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+CONFIG_TOUCHSCREEN_COLIBRI_VF50=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_VF610_SEMA4=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_HW_RANDOM=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_DSPI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SENSORS_IIO_HWMON=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_RC_SUPPORT=y
+# CONFIG_RC_MAP is not set
+# CONFIG_RC_DECODERS is not set
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+# CONFIG_USB_GSPCA is not set
+CONFIG_DRM=y
+CONFIG_DRM_FSL_DCU=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_FSL_SAI_WM9712=y
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_HIDRAW=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_FSL_USB2=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+# CONFIG_MX3_IPU is not set
+CONFIG_ARM_TIMER_SP804=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_VF610_CM4_RPROC=m
+CONFIG_IMX_RPMSG_PINGPONG=m
+CONFIG_IMX_RPMSG_TTY=m
+CONFIG_VF610_RPMSG=m
+CONFIG_SOC_BUS_VF610=y
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_VF610_ADC=y
+CONFIG_VF610_DAC=y
+CONFIG_IIO_SYSFS_TRIGGER=y
+CONFIG_PWM=y
+CONFIG_PWM_FSL_FTM=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_VF610_OCOTP=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_OVERLAY_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_NTFS_RW=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 1d45320ee125..ece04a457486 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -95,7 +95,7 @@ void __init init_IRQ(void)
outer_cache.write_sec = machine_desc->l2c_write_sec;
ret = l2x0_of_init(machine_desc->l2c_aux_val,
machine_desc->l2c_aux_mask);
- if (ret)
+ if (ret && ret != -ENODEV)
pr_err("L2C: failed to init: %d\n", ret);
}
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fb689d813b09..1fffae129a4a 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -90,8 +90,11 @@ ifeq ($(CONFIG_SUSPEND),y)
AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
+AFLAGS_suspend-vf610.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_VF610) += suspend-vf610.o
endif
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
+obj-$(CONFIG_SOC_VF610) += pm-vf610.o
obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index e2d53839fceb..94d93a3b3b58 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -75,6 +75,13 @@ enum mxc_cpu_pwr_mode {
STOP_POWER_OFF, /* STOP + SRPG */
};
+enum vf610_cpu_pwr_mode {
+ VF610_RUN,
+ VF610_LP_RUN,
+ VF610_STOP,
+ VF610_LP_STOP,
+};
+
enum mx3_cpu_pwr_mode {
MX3_RUN,
MX3_WAIT,
@@ -119,11 +126,13 @@ void v7_cpu_resume(void);
void imx53_suspend(void __iomem *ocram_vbase);
extern const u32 imx53_suspend_sz;
void imx6_suspend(void __iomem *ocram_vbase);
+void vf610_suspend(void __iomem *ocram_vbase);
#else
static inline void v7_cpu_resume(void) {}
static inline void imx53_suspend(void __iomem *ocram_vbase) {}
static const u32 imx53_suspend_sz;
static inline void imx6_suspend(void __iomem *ocram_vbase) {}
+static inline void vf610_suspend(void __iomem *ocram_vbase) {}
#endif
void imx6_pm_ccm_init(const char *ccm_compat);
@@ -132,6 +141,7 @@ void imx6dl_pm_init(void);
void imx6sl_pm_init(void);
void imx6sx_pm_init(void);
void imx6ul_pm_init(void);
+void vf610_pm_init(void);
#ifdef CONFIG_PM
void imx51_pm_init(void);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index b20f6c14eda5..5ba668feea65 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -11,6 +11,13 @@
#include <linux/irqchip.h>
#include <asm/mach/arch.h>
#include <asm/hardware/cache-l2x0.h>
+#include "common.h"
+
+static void __init vf610_init_machine(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ vf610_pm_init();
+}
static const char * const vf610_dt_compat[] __initconst = {
"fsl,vf500",
@@ -24,5 +31,6 @@ static const char * const vf610_dt_compat[] __initconst = {
DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF5xx/VF6xx (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
+ .init_machine = vf610_init_machine,
.dt_compat = vf610_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-imx/pm-vf610.c b/arch/arm/mach-imx/pm-vf610.c
new file mode 100644
index 000000000000..5a3df0caf23a
--- /dev/null
+++ b/arch/arm/mach-imx/pm-vf610.c
@@ -0,0 +1,704 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2014 Toradex AG
+ *
+ * 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
+ */
+
+#ifdef DEBUG
+#define pr_pmdebug(fmt, ...) pr_info("PM: VF610: " fmt "\n", ##__VA_ARGS__)
+#else
+#define pr_pmdebug(fmt, ...)
+#endif
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include "common.h"
+
+#define DDRMC_PHY_OFFSET 0x400
+
+#define CCR 0x0
+#define BM_CCR_FIRC_EN (0x1 << 16)
+#define BM_CCR_FXOSC_EN (0x1 << 12)
+
+#define CCSR 0x8
+#define BM_CCSR_DDRC_CLK_SEL (0x1 << 6)
+#define BM_CCSR_FAST_CLK_SEL (0x1 << 5)
+#define BM_CCSR_SLOW_CLK_SEL (0x1 << 4)
+#define BM_CCSR_SYS_CLK_SEL_MASK (0x7 << 0)
+
+#define CACRR 0xc
+
+#define CLPCR 0x2c
+#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_ANADIG_STOP_MODE (0x1 << 8)
+#define BM_CLPCR_FXOSC_BYPSEN (0x1 << 10)
+#define BM_CLPCR_FXOSC_PWRDWN (0x1 << 11)
+#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
+#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 24)
+#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 25)
+
+#define CGPR 0x64
+#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
+
+#define GPC_PGCR 0x0
+#define BM_PGCR_DS_STOP (0x1 << 7)
+#define BM_PGCR_DS_LPSTOP (0x1 << 6)
+#define BM_PGCR_WB_STOP (0x1 << 4)
+#define BM_PGCR_HP_OFF (0x1 << 3)
+#define BM_PGCR_PG_PD1 (0x1 << 0)
+
+#define GPC_LPMR 0x40
+#define BM_LPMR_RUN 0x0
+#define BM_LPMR_STOP 0x2
+
+#define ANATOP_PLL1_CTRL 0x270
+#define ANATOP_PLL2_CTRL 0x30
+#define ANATOP_PLL2_PFD 0x100
+#define BM_PLL_POWERDOWN (0x1 << 12)
+#define BM_PLL_ENABLE (0x1 << 13)
+#define BM_PLL_BYPASS (0x1 << 16)
+#define BM_PLL_LOCK (0x1 << 31)
+#define BM_PLL_PFD2_CLKGATE (0x1 << 15)
+#define BM_PLL_USB_POWER (0x1 << 12)
+#define BM_PLL_EN_USB_CLKS (0x1 << 6)
+
+#define VF610_DDRMC_IO_NUM 94
+#define VF610_IOMUX_DDR_IO_NUM 48
+#define VF610_ANATOP_IO_NUM 2
+
+static struct vf610_cpu_pm_info *pm_info;
+static void __iomem *suspend_ocram_base;
+static void (*vf610_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+static bool mem_suspend_available;
+
+#ifdef DEBUG
+static void __iomem *uart_membase;
+static unsigned long uart_clk;
+#endif
+
+static const u32 vf610_iomuxc_ddr_io_offset[] __initconst = {
+ 0x220, 0x224, 0x228, 0x22c, 0x230, 0x234, 0x238, 0x23c,
+ 0x240, 0x244, 0x248, 0x24c, 0x250, 0x254, 0x258, 0x25c,
+ 0x260, 0x264, 0x268, 0x26c, 0x270, 0x274, 0x278, 0x27c,
+ 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, 0x298, 0x29c,
+ 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc,
+ 0x2c0, 0x2c4, 0x2c8, 0x2cc, 0x2d0, 0x2d4, 0x2d8, 0x21c,
+};
+
+
+static const u32 vf610_ddrmc_io_offset[] __initconst = {
+ 0x00, 0x08, 0x28, 0x2c, 0x30, 0x34, 0x38,
+ 0x40, 0x44, 0x48, 0x50, 0x54, 0x58, 0x5c,
+ 0x60, 0x64, 0x68, 0x70, 0x74, 0x78, 0x7c,
+ 0x84, 0x88, 0x98, 0x9c, 0xa4, 0xc0,
+ 0x108, 0x10c, 0x114, 0x118, 0x120, 0x124,
+ 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c,
+ 0x148, 0x15c, 0x160, 0x164, 0x16c, 0x180,
+ 0x184, 0x188, 0x18c, 0x198, 0x1a4, 0x1a8,
+ 0x1b8, 0x1d4, 0x1d8, 0x1e0, 0x1e4, 0x1e8,
+ 0x1ec, 0x1f0, 0x1f8, 0x210, 0x224, 0x228,
+ 0x22c, 0x230, 0x23c, 0x240, 0x244, 0x248,
+ 0x24c, 0x250, 0x25c, 0x268, 0x26c, 0x278,
+ 0x268
+};
+
+static const u32 vf610_ddrmc_phy_io_offset[] __initconst = {
+ 0x00, 0x04, 0x08, 0x0c, 0x10,
+ 0x40, 0x44, 0x48, 0x4c, 0x50,
+ 0x80, 0x84, 0x88, 0x8c, 0x90,
+ 0xc4, 0xc8, 0xd0
+};
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * vf610_suspend code
+ * PM_INFO structure(vf610_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct vf610_pm_base {
+ phys_addr_t pbase;
+ void __iomem *vbase;
+};
+
+struct vf610_pm_socdata {
+ const char *anatop_compat;
+ const char *scsc_compat;
+ const char *wkpu_compat;
+ const char *ccm_compat;
+ const char *gpc_compat;
+ const char *src_compat;
+ const char *ddrmc_compat;
+ const char *iomuxc_compat;
+};
+
+static const struct vf610_pm_socdata vf610_pm_data __initconst = {
+ .anatop_compat = "fsl,vf610-anatop",
+ .scsc_compat = "fsl,vf610-scsc",
+ .wkpu_compat = "fsl,vf610-wkpu",
+ .ccm_compat = "fsl,vf610-ccm",
+ .gpc_compat = "fsl,vf610-gpc",
+ .src_compat = "fsl,vf610-src",
+ .ddrmc_compat = "fsl,vf610-ddrmc",
+ .iomuxc_compat = "fsl,vf610-iomuxc",
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-vf610.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-vf610.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct vf610_cpu_pm_info {
+ phys_addr_t pbase; /* The physical address of pm_info. */
+ phys_addr_t resume_addr; /* The physical resume address for asm code */
+ u32 cpu_type; /* Currently not used, leave it for alignment */
+ u32 pm_info_size; /* Size of pm_info. */
+ struct vf610_pm_base anatop_base;
+ struct vf610_pm_base scsc_base;
+ struct vf610_pm_base wkpu_base;
+ struct vf610_pm_base ccm_base;
+ struct vf610_pm_base gpc_base;
+ struct vf610_pm_base src_base;
+ struct vf610_pm_base ddrmc_base;
+ struct vf610_pm_base iomuxc_base;
+ struct vf610_pm_base l2_base;
+ u32 ccm_cacrr;
+ u32 ccm_ccsr;
+ u32 ddrmc_io_num; /* Number of MMDC IOs which need saved/restored. */
+ u32 ddrmc_io_val[VF610_DDRMC_IO_NUM][2]; /* To save offset and value */
+ u32 iomux_ddr_io_num;
+ u32 iomux_ddr_io_val[VF610_IOMUX_DDR_IO_NUM][2];
+} __aligned(8);
+
+#ifdef DEBUG
+static void vf610_uart_reinit(unsigned long int rate, unsigned long int baud)
+{
+ u8 tmp, c2;
+ u16 sbr, brfa;
+
+ /* UART_C2 */
+ c2 = __raw_readb(uart_membase + 0x3);
+ __raw_writeb(0, uart_membase + 0x3);
+
+ sbr = (u16) (rate / (baud * 16));
+ brfa = (rate / baud) - (sbr * 16);
+
+ tmp = ((sbr & 0x1f00) >> 8);
+ __raw_writeb(tmp, uart_membase + 0x0);
+ tmp = sbr & 0x00ff;
+ __raw_writeb(tmp, uart_membase + 0x1);
+
+ /* UART_C4 */
+ __raw_writeb(brfa & 0xf, uart_membase + 0xa);
+
+ __raw_writeb(c2, uart_membase + 0x3);
+}
+#else
+#define vf610_uart_reinit(rate, baud)
+#endif
+
+static void vf610_set(void __iomem *pll_base, u32 mask)
+{
+ writel(readl(pll_base) | mask, pll_base);
+}
+
+static void vf610_clr(void __iomem *pll_base, u32 mask)
+{
+ writel(readl(pll_base) & ~mask, pll_base);
+}
+
+int vf610_set_lpm(enum vf610_cpu_pwr_mode mode)
+{
+ void __iomem *ccm_base = pm_info->ccm_base.vbase;
+ void __iomem *gpc_base = pm_info->gpc_base.vbase;
+ void __iomem *anatop = pm_info->anatop_base.vbase;
+ u32 ccr = readl_relaxed(ccm_base + CCR);
+ u32 ccsr = readl_relaxed(ccm_base + CCSR);
+ u32 cacrr = readl_relaxed(ccm_base + CACRR);
+ u32 cclpcr = 0;
+ u32 gpc_pgcr = 0;
+
+ switch (mode) {
+ case VF610_LP_STOP:
+ /* Store clock settings */
+ pm_info->ccm_ccsr = ccsr;
+ pm_info->ccm_cacrr = cacrr;
+
+ ccr |= BM_CCR_FIRC_EN;
+ writel_relaxed(ccr, ccm_base + CCR);
+
+ cclpcr |= BM_CLPCR_ANADIG_STOP_MODE;
+ cclpcr |= BM_CLPCR_SBYOS;
+
+ cclpcr |= BM_CLPCR_MASK_SCU_IDLE;
+ cclpcr |= BM_CLPCR_MASK_L2CC_IDLE;
+ cclpcr |= BM_CLPCR_MASK_CORE1_WFI;
+ writel_relaxed(cclpcr, ccm_base + CLPCR);
+
+ gpc_pgcr |= BM_PGCR_DS_STOP;
+ gpc_pgcr |= BM_PGCR_DS_LPSTOP;
+ gpc_pgcr |= BM_PGCR_WB_STOP;
+ gpc_pgcr |= BM_PGCR_HP_OFF;
+ gpc_pgcr |= BM_PGCR_PG_PD1;
+ writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR);
+ break;
+ case VF610_STOP:
+ cclpcr &= ~BM_CLPCR_ANADIG_STOP_MODE;
+ cclpcr |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+ cclpcr |= BM_CLPCR_SBYOS;
+ writel_relaxed(cclpcr, ccm_base + CLPCR);
+
+ gpc_pgcr |= BM_PGCR_DS_STOP;
+ gpc_pgcr |= BM_PGCR_HP_OFF;
+ writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR);
+
+ /* fall-through */
+ case VF610_LP_RUN:
+ /* Store clock settings */
+ pm_info->ccm_ccsr = ccsr;
+ pm_info->ccm_cacrr = cacrr;
+
+ ccr |= BM_CCR_FIRC_EN;
+ writel_relaxed(ccr, ccm_base + CCR);
+
+ /* Enable PLL2 for DDR clock */
+ vf610_set(anatop + ANATOP_PLL2_CTRL, BM_PLL_ENABLE);
+ vf610_clr(anatop + ANATOP_PLL2_CTRL, BM_PLL_POWERDOWN);
+ vf610_clr(anatop + ANATOP_PLL2_CTRL, BM_PLL_BYPASS);
+ while (!(readl(anatop + ANATOP_PLL2_CTRL) & BM_PLL_LOCK));
+ vf610_clr(anatop + ANATOP_PLL2_PFD, BM_PLL_PFD2_CLKGATE);
+
+ /* Switch internal OSC's */
+ ccsr &= ~BM_CCSR_FAST_CLK_SEL;
+ ccsr &= ~BM_CCSR_SLOW_CLK_SEL;
+
+ /* Select PLL2 as DDR clock */
+ ccsr &= ~BM_CCSR_DDRC_CLK_SEL;
+ writel_relaxed(ccsr, ccm_base + CCSR);
+
+ ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK;
+ writel_relaxed(ccsr, ccm_base + CCSR);
+ vf610_uart_reinit(4000000UL, 115200);
+
+ vf610_set(anatop + ANATOP_PLL1_CTRL, BM_PLL_BYPASS);
+ writel_relaxed(BM_LPMR_STOP, gpc_base + GPC_LPMR);
+ break;
+ case VF610_RUN:
+ writel_relaxed(BM_LPMR_RUN, gpc_base + GPC_LPMR);
+
+ vf610_clr(anatop + ANATOP_PLL1_CTRL, BM_PLL_BYPASS);
+ while(!(readl(anatop + ANATOP_PLL1_CTRL) & BM_PLL_LOCK));
+
+ /* Restore clock settings */
+ writel(pm_info->ccm_ccsr, ccm_base + CCSR);
+
+ vf610_uart_reinit(uart_clk, 115200);
+ pr_pmdebug("resuming, uart_reinit done");
+
+ /* Disable PLL2 if not needed */
+ if (pm_info->ccm_ccsr & BM_CCSR_DDRC_CLK_SEL)
+ vf610_set(anatop + ANATOP_PLL2_CTRL, BM_PLL_POWERDOWN);
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vf610_suspend_finish(unsigned long val)
+{
+ if (!vf610_suspend_in_ocram_fn) {
+ cpu_do_idle();
+ } else {
+ /*
+ * call low level suspend function in ocram,
+ * as we need to float DDR IO.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+ outer_flush_all();
+ vf610_suspend_in_ocram_fn(suspend_ocram_base);
+ }
+
+ return 0;
+}
+
+static int vf610_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ vf610_set_lpm(VF610_STOP);
+ flush_cache_all();
+
+ /* zzZZZzzz */
+ cpu_do_idle();
+
+ vf610_set_lpm(VF610_RUN);
+ break;
+ case PM_SUSPEND_MEM:
+ vf610_set_lpm(VF610_LP_STOP);
+
+ cpu_suspend(0, vf610_suspend_finish);
+ outer_resume();
+
+ vf610_set_lpm(VF610_RUN);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vf610_pm_valid(suspend_state_t state)
+{
+ return (state == PM_SUSPEND_STANDBY ||
+ (state == PM_SUSPEND_MEM && mem_suspend_available));
+}
+
+static const struct platform_suspend_ops vf610_pm_ops = {
+ .enter = vf610_pm_enter,
+ .valid = vf610_pm_valid,
+};
+
+static int __init imx_pm_get_base(struct vf610_pm_base *base,
+ const char *compat)
+{
+ struct device_node *node;
+ struct resource res;
+ int ret = 0;
+
+ node = of_find_compatible_node(NULL, NULL, compat);
+ if (!node) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret)
+ goto put_node;
+
+ base->pbase = res.start;
+ base->vbase = ioremap(res.start, resource_size(&res));
+
+ if (!base->vbase)
+ ret = -ENOMEM;
+
+put_node:
+ of_node_put(node);
+out:
+ return ret;
+}
+
+#ifdef DEBUG
+static int __init vf610_uart_init(void)
+{
+ struct device_node *dn;
+ const char *name;
+ struct clk *clk;
+ int ret;
+
+ name = of_get_property(of_chosen, "stdout-path", NULL);
+ if (name == NULL)
+ return -ENODEV;
+
+ dn = of_find_node_by_path(name);
+ if (!dn)
+ return -ENODEV;
+
+ clk = of_clk_get(dn, 0);
+
+ if (!clk) {
+ ret = PTR_ERR(clk);
+ goto put_node;
+ }
+
+ uart_clk = clk_get_rate(clk);
+
+ uart_membase = of_iomap(dn, 0);
+ if (!clk) {
+ ret = -ENOMEM;
+ goto put_node;
+ }
+
+ ret = 0;
+
+put_node:
+ of_node_put(dn);
+ return ret;
+}
+#endif
+
+static void vf610_power_off(void)
+{
+ void __iomem *gpc_base = pm_info->gpc_base.vbase;
+ u32 gpc_pgcr;
+
+ /*
+ * Power gate Power Domain 1
+ */
+ gpc_pgcr = readl_relaxed(gpc_base + GPC_PGCR);
+ gpc_pgcr |= BM_PGCR_PG_PD1;
+ writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR);
+
+ /* Set low power mode */
+ vf610_set_lpm(VF610_STOP);
+}
+
+static int __init vf610_suspend_mem_init(const struct vf610_pm_socdata *socdata)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+ bool has_cke_reset_pulls = false;
+ phys_addr_t ocram_pbase;
+ struct gen_pool *ocram_pool;
+ size_t ocram_size;
+ unsigned long ocram_base;
+ int ret = 0, reg = 0;
+ int i;
+
+ node = of_find_compatible_node(NULL, NULL, socdata->ddrmc_compat);
+ if (node) {
+ has_cke_reset_pulls =
+ of_property_read_bool(node, "fsl,has-cke-reset-pulls");
+
+ of_node_put(node);
+ }
+
+ if (!has_cke_reset_pulls) {
+ pr_info("PM: No CKE/RESET pulls, disable Suspend-to-RAM\n");
+ return -ENODEV;
+ }
+
+ node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+ if (!node) {
+ pr_warn("%s: failed to find ocram node!\n", __func__);
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ pr_warn("%s: failed to find ocram device!\n", __func__);
+ ret = -ENODEV;
+ goto put_node;
+ }
+
+ ocram_pool = gen_pool_get(&pdev->dev, "stbyram1");
+ if (!ocram_pool) {
+ pr_warn("%s: ocram pool unavailable!\n", __func__);
+ ret = -ENODEV;
+ goto put_node;
+ }
+
+ ocram_size = gen_pool_size(ocram_pool);
+ ocram_base = gen_pool_alloc(ocram_pool, ocram_size);
+ if (!ocram_base) {
+ pr_warn("%s: unable to alloc ocram!\n", __func__);
+ ret = -ENOMEM;
+ goto put_node;
+ }
+
+ ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+ suspend_ocram_base = __arm_ioremap_exec(ocram_pbase, ocram_size, false);
+
+ pm_info = suspend_ocram_base;
+ pm_info->pbase = ocram_pbase;
+ pm_info->resume_addr = virt_to_phys(cpu_resume);
+
+ pm_info->ddrmc_io_num = VF610_DDRMC_IO_NUM;
+
+ ret = imx_pm_get_base(&pm_info->ddrmc_base, socdata->ddrmc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get ddrmc base %d!\n", __func__, ret);
+ goto put_node;
+ }
+
+ ret = imx_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
+ goto iomuxc_map_failed;
+ }
+
+ /* Store DDRMC registers */
+ for (i = 0; i < ARRAY_SIZE(vf610_ddrmc_io_offset); i++, reg++) {
+ pm_info->ddrmc_io_val[reg][0] = vf610_ddrmc_io_offset[i];
+ pm_info->ddrmc_io_val[reg][1] =
+ readl_relaxed(pm_info->ddrmc_base.vbase +
+ vf610_ddrmc_io_offset[i]);
+ }
+
+ /* Store DDRMC PHY registers */
+ for (i = 0; i < ARRAY_SIZE(vf610_ddrmc_phy_io_offset); i++, reg++) {
+ pm_info->ddrmc_io_val[reg][0] = vf610_ddrmc_phy_io_offset[i] +
+ DDRMC_PHY_OFFSET;
+ pm_info->ddrmc_io_val[reg][1] =
+ readl_relaxed(pm_info->ddrmc_base.vbase +
+ DDRMC_PHY_OFFSET + vf610_ddrmc_phy_io_offset[i]);
+ }
+
+ /* Store IOMUX DDR pad registers */
+ pm_info->iomux_ddr_io_num = VF610_IOMUX_DDR_IO_NUM;
+ for (i = 0; i < ARRAY_SIZE(vf610_iomuxc_ddr_io_offset); i++) {
+ pm_info->iomux_ddr_io_val[i][0] = vf610_iomuxc_ddr_io_offset[i];
+ pm_info->iomux_ddr_io_val[i][1] =
+ readl_relaxed(pm_info->iomuxc_base.vbase +
+ vf610_iomuxc_ddr_io_offset[i]);
+ }
+
+ vf610_suspend_in_ocram_fn = fncpy(
+ suspend_ocram_base + sizeof(*pm_info),
+ &vf610_suspend, ocram_size - sizeof(*pm_info));
+
+ pr_info("PM: CKE/RESET pulls available, enable Suspend-to-RAM\n");
+ goto put_node;
+
+iomuxc_map_failed:
+ iounmap(pm_info->ddrmc_base.vbase);
+put_node:
+ of_node_put(node);
+
+ return ret;
+}
+
+static int __init vf610_suspend_init(const struct vf610_pm_socdata *socdata)
+{
+ int ret;
+ struct device_node *soc_node;
+
+#ifdef DEBUG
+ ret = vf610_uart_init();
+ if (ret < 0)
+ return ret;
+#endif
+
+ soc_node = of_find_node_by_path("/soc");
+ if (soc_node == NULL)
+ return -ENODEV;
+
+ if (of_property_read_bool(soc_node, "fsl,use-lpm-poweroff"))
+ pm_power_off = vf610_power_off;
+
+ if (vf610_suspend_mem_init(socdata)) {
+ /*
+ * Suspend to memory for some reason not available, use DDR
+ * for standby mode
+ */
+ pm_info = kzalloc(sizeof(*pm_info), GFP_KERNEL);
+ } else {
+ mem_suspend_available = true;
+ }
+
+ pm_info->pm_info_size = sizeof(*pm_info);
+
+ ret = imx_pm_get_base(&pm_info->anatop_base, socdata->anatop_compat);
+ if (ret) {
+ pr_warn("%s: failed to get anatop base %d!\n", __func__, ret);
+ return ret;
+ }
+
+ ret = imx_pm_get_base(&pm_info->scsc_base, socdata->scsc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get scsc base %d!\n", __func__, ret);
+ goto scsc_map_failed;
+ }
+
+ ret = imx_pm_get_base(&pm_info->ccm_base, socdata->ccm_compat);
+ if (ret) {
+ pr_warn("%s: failed to get ccm base %d!\n", __func__, ret);
+ goto ccm_map_failed;
+ }
+
+ ret = imx_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
+ if (ret) {
+ pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
+ goto gpc_map_failed;
+ }
+
+ ret = imx_pm_get_base(&pm_info->src_base, socdata->src_compat);
+ if (ret) {
+ pr_warn("%s: failed to get src base %d!\n", __func__, ret);
+ goto src_map_failed;
+ }
+
+ ret = imx_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
+ if (ret == -ENODEV)
+ ret = 0;
+ if (ret) {
+ pr_warn("%s: failed to get pl310-cache base %d!\n",
+ __func__, ret);
+ goto pl310_cache_map_failed;
+ }
+
+ suspend_set_ops(&vf610_pm_ops);
+
+ return 0;
+
+pl310_cache_map_failed:
+ iounmap(pm_info->src_base.vbase);
+src_map_failed:
+ iounmap(pm_info->gpc_base.vbase);
+gpc_map_failed:
+ iounmap(pm_info->ccm_base.vbase);
+ccm_map_failed:
+ iounmap(pm_info->scsc_base.vbase);
+scsc_map_failed:
+ iounmap(pm_info->anatop_base.vbase);
+
+ if (mem_suspend_available) {
+ iounmap(pm_info->ddrmc_base.vbase);
+ iounmap(pm_info->iomuxc_base.vbase);
+ }
+
+ return ret;
+}
+
+void __init vf610_pm_init(void)
+{
+ int ret;
+
+ if (IS_ENABLED(CONFIG_SUSPEND)) {
+ ret = vf610_suspend_init(&vf610_pm_data);
+ if (ret)
+ pr_warn("%s: No DDR LPM support with suspend %d!\n",
+ __func__, ret);
+ }
+}
+
diff --git a/arch/arm/mach-imx/suspend-vf610.S b/arch/arm/mach-imx/suspend-vf610.S
new file mode 100644
index 000000000000..595dd4e2c74c
--- /dev/null
+++ b/arch/arm/mach-imx/suspend-vf610.S
@@ -0,0 +1,448 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2015 Toradex AG
+ *
+ * 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 <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * Better to follow below rules to use ARM registers:
+ * r0: pm_info structure address;
+ * r1 ~ r4: for saving pm_info members;
+ * r5 ~ r10: free registers;
+ * r11: io base address.
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ * .
+ * .
+ * .
+ * ^
+ * ^
+ * ^
+ * vf610_suspend code
+ * PM_INFO structure(vf610_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+/*
+ * Below offsets are based on struct vf610_cpu_pm_info
+ * which defined in arch/arm/mach-imx/pm-vf610.c, this
+ * structure contains necessary pm info for low level
+ * suspend related code.
+ */
+#define PM_INFO_PBASE_OFFSET 0x0
+#define PM_INFO_RESUME_ADDR_OFFSET 0x4
+#define PM_INFO_CPU_TYPE_OFFSET 0x8
+#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
+#define PM_INFO_VF610_ANATOP_P_OFFSET 0x10
+#define PM_INFO_VF610_ANATOP_V_OFFSET 0x14
+#define PM_INFO_VF610_SCSC_P_OFFSET 0x18
+#define PM_INFO_VF610_SCSC_V_OFFSET 0x1C
+#define PM_INFO_VF610_WKPU_P_OFFSET 0x20
+#define PM_INFO_VF610_WKPU_V_OFFSET 0x24
+#define PM_INFO_VF610_CCM_P_OFFSET 0x28
+#define PM_INFO_VF610_CCM_V_OFFSET 0x2C
+#define PM_INFO_VF610_GPC_P_OFFSET 0x30
+#define PM_INFO_VF610_GPC_V_OFFSET 0x34
+#define PM_INFO_VF610_SRC_P_OFFSET 0x38
+#define PM_INFO_VF610_SRC_V_OFFSET 0x3C
+#define PM_INFO_VF610_DDRMC_P_OFFSET 0x40
+#define PM_INFO_VF610_DDRMC_V_OFFSET 0x44
+#define PM_INFO_VF610_IOMUXC_P_OFFSET 0x48
+#define PM_INFO_VF610_IOMUXC_V_OFFSET 0x4c
+#define PM_INFO_VF610_L2_P_OFFSET 0x50
+#define PM_INFO_VF610_L2_V_OFFSET 0x54
+#define PM_INFO_CCM_CACRR 0x58
+#define PM_INFO_CCM_CCSR 0x5c
+#define PM_INFO_DDRMC_IO_NUM_OFFSET 0x60
+#define PM_INFO_DDRMC_IO_VAL_OFFSET 0x64
+#define PM_INFO_IOMUXC_DDR_IO_NUM_OFFSET (0x64 + 94 * 2 * 4)
+#define PM_INFO_IOMUXC_DDR_IO_VAL_OFFSET (0x68 + 94 * 2 * 4)
+
+#define VF610_ANADIG_PLL2_CTRL 0x30
+
+#define VF610_ANADIG_MISC0 0x150
+#define VF610_ANADIG_MISC0_CLK_24M_IRC_XTAL_SEL (0x1 < 13)
+
+#define VF610_ANADIG_PLL1_CTRL 0x270
+
+#define VF610_ANADIG_POWERDOWN (1 << 12)
+#define VF610_ANADIG_ENABLE (1 << 13)
+#define VF610_ANADIG_BYPASS (1 << 16)
+#define VF610_ANADIG_LOCK (1 << 31)
+
+#define VF610_SCSC_SIRC 0x0
+#define VF610_SCSC_SIRC_SIRC_EN (0x1 << 0)
+#define VF610_SCSC_SOSC 0x4
+#define VF610_SCSC_SOSC_SOSC_EN (0x1 << 0)
+
+#define VF610_GPC_PGCR 0x0
+#define VF610_GPC_LPMR 0x40
+
+#define VF610_CCM_CCR 0x00
+#define VF610_CCM_CCR_FXOSC_EN (0x1 << 12)
+
+#define VF610_CCM_CCSR 0x08
+#define VF610_CCM_CCSR_DDRC_CLK_SEL (0x1 << 6)
+#define VF610_CCM_CCSR_FAST_CLK_SEL (0x1 << 5)
+
+#define VF610_CCM_CACRR 0x0C
+
+#define VF610_CCM_CLPCR 0x2C
+#define VF610_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define VF610_CCM_CLPCR_FXOSC_PWRDWN (0x1 << 11)
+
+#define VF610_CCM_CCGR0 0x40
+#define VF610_CCM_CCGR2 0x48
+#define VF610_CCM_CCGR3 0x4C
+#define VF610_CCM_CCGR4 0x50
+#define VF610_CCM_CCGR6 0x58
+
+#define VF610_SRC_GPR0 0x20
+#define VF610_SRC_GPR1 0x24
+#define VF610_SRC_MISC2 0x54
+
+#define VF610_DDRMC_CR00 0x0
+#define VF610_DDRMC_CR00_START (0x1 << 0)
+
+#define VF610_DDRMC_CR33 0x84
+#define VF610_DDRMC_CR33_PWUP_SREF_EX (0x1 << 0)
+
+#define VF610_DDRMC_CR34 0x88
+
+#define VF610_DDRMC_CR35 0x8C
+#define VF610_DDRMC_CR35_LP_CMD(cmd) ((cmd) << 8)
+
+#define VF610_DDRMC_CR80 0x140
+#define VF610_DDRMC_CR80_LP_COMPLETE (0x1 << 9)
+#define VF610_DDRMC_CR80_INIT_COMPLETE (0x1 << 8)
+#define VF610_DDRMC_CR81 0x144
+
+ .align 3
+
+ /*
+ * Take DDR RAM out of Low-Power mode
+ */
+ .macro resume_ddrmc ddrmc_base
+
+ /* Clear low power complete flag... */
+ ldr r6, =VF610_DDRMC_CR80_LP_COMPLETE
+ str r6, [\ddrmc_base, #VF610_DDRMC_CR81]
+
+ ldr r6, [\ddrmc_base, #VF610_DDRMC_CR35]
+ orr r6, r6, #VF610_DDRMC_CR35_LP_CMD(0x9)
+ str r6, [\ddrmc_base, #VF610_DDRMC_CR35]
+
+1:
+ ldr r5, [\ddrmc_base, #VF610_DDRMC_CR80]
+ ands r5, r5, #VF610_DDRMC_CR80_LP_COMPLETE
+ beq 1b
+
+ .endm
+
+ .macro enable_syspll pll_base
+
+ ldr r5, [\pll_base]
+ orr r5, r5, #VF610_ANADIG_ENABLE
+ bic r5, r5, #VF610_ANADIG_POWERDOWN
+ bic r5, r5, #VF610_ANADIG_BYPASS
+ str r5, [\pll_base]
+
+1:
+ ldr r5, [\pll_base]
+ tst r5, #VF610_ANADIG_LOCK
+ beq 1b
+
+ .endm
+
+ENTRY(vf610_suspend)
+ ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
+ ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+ ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
+ ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+ /*
+ * make sure TLB contain the addr we want,
+ * as we will access them after MMDC IO floated.
+ */
+
+ ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET]
+ ldr r6, [r11, #0x0]
+ ldr r11, [r0, #PM_INFO_VF610_GPC_V_OFFSET]
+ ldr r6, [r11, #0x0]
+ ldr r11, [r0, #PM_INFO_VF610_SRC_V_OFFSET]
+ ldr r6, [r11, #0x0]
+ ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET]
+ ldr r6, [r11, #0x0]
+
+ ldr r11, [r0, #PM_INFO_VF610_SRC_V_OFFSET]
+
+ /* Disable DDR RESET */
+ ldr r6, [r11, #VF610_SRC_MISC2]
+ orr r6, r6, #0x1
+ str r6, [r11, #VF610_SRC_MISC2]
+
+ /* Set ENTRY/ARGUMENT register */
+ ldr r6, =vf610_suspend
+ ldr r7, =resume
+ sub r7, r7, r6
+ add r8, r1, r4
+ add r9, r8, r7
+ str r9, [r11, #VF610_SRC_GPR0]
+ str r1, [r11, #VF610_SRC_GPR1]
+
+ /* Put memory in self refresh... */
+ ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET]
+
+ ldr r6, =VF610_DDRMC_CR80_LP_COMPLETE
+ str r6, [r11, #VF610_DDRMC_CR81]
+
+ ldr r6, [r11, #VF610_DDRMC_CR35]
+ orr r6, r6, #VF610_DDRMC_CR35_LP_CMD(0xA)
+ str r6, [r11, #VF610_DDRMC_CR35]
+
+ddrmc_cmd_complete:
+ /* A Unfixed module seems to hang at this read.... */
+ ldr r5, [r11, #VF610_DDRMC_CR80]
+ ands r5, r5, #VF610_DDRMC_CR80_LP_COMPLETE
+ beq ddrmc_cmd_complete
+
+ /* switch to internal FIRC */
+ ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET]
+ ldr r5, [r11, #VF610_CCM_CCSR]
+ bic r5, r5, #0x30 /* FAST_/SLOW_CLK_SEL */
+ str r5, [r11, #VF610_CCM_CCSR]
+ bic r5, r5, #0x07 /* SYS_CLK_SEL */
+ str r5, [r11, #VF610_CCM_CCSR]
+
+ /* LP-Mode: STOP */
+ ldr r11, [r0, #PM_INFO_VF610_GPC_V_OFFSET]
+ ldr r6, =0x02
+ str r6, [r11, #VF610_GPC_LPMR]
+
+ /* Zzz, enter stop mode */
+ wfi
+ nop
+ nop
+ nop
+ nop
+
+ /* If we get here, there is already an interrupt pending. Restore... */
+ ldr r6, =0x00
+ str r6, [r11, #VF610_GPC_LPMR]
+
+ /* Get previous CCSR/CACRR settings */
+ ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET]
+ ldr r5, [r0, #PM_INFO_CCM_CCSR]
+ str r5, [r11, #VF610_CCM_CCSR]
+
+ ldr r5, [r0, #PM_INFO_CCM_CACRR]
+ str r5, [r11, #VF610_CCM_CACRR]
+
+ ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET]
+ resume_ddrmc r11
+
+ ret lr
+
+/* Resume path if CPU uses the SRC_GPR0 (PERSISTENT_ENTRY0) */
+resume:
+ /* invalidate L1 I-cache first */
+ mov r6, #0x0
+ mcr p15, 0, r6, c7, c5, 0
+ mcr p15, 0, r6, c7, c5, 6
+
+ /* enable the Icache and branch prediction */
+ mov r6, #0x1800
+ mcr p15, 0, r6, c1, c0, 0
+ isb
+
+ ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET]
+
+ ldr r5, [r11, #VF610_CCM_CCSR]
+ orr r5, r5, #(1 << 13)
+ str r5, [r11, #VF610_CCM_CCSR]
+
+ /* enable UART0 */
+ ldr r5, [r11, #VF610_CCM_CCGR0]
+ orr r5, r5, #0xC000
+ str r5, [r11, #VF610_CCM_CCGR0]
+
+ /* enable IOMUX, PORT A-E */
+ ldr r5, [r11, #VF610_CCM_CCGR2]
+ ldr r6, =0xFFF0000
+ orr r5, r5, r6
+ str r5, [r11, #VF610_CCM_CCGR2]
+
+ /* enable ANADIG and SCSM */
+ ldr r5, [r11, #VF610_CCM_CCGR3]
+ orr r5, r5, #0x33
+ str r5, [r11, #VF610_CCM_CCGR3]
+
+ /* enable GPC, CCM and WKUP */
+ ldr r5, [r11, #VF610_CCM_CCGR4]
+ orr r5, r5, #0x3f00000
+ str r5, [r11, #VF610_CCM_CCGR4]
+
+ /* enable mmdc */
+ ldr r5, [r11, #VF610_CCM_CCGR6]
+ orr r5, r5, #0x30000000
+ str r5, [r11, #VF610_CCM_CCGR6]
+
+ /* Mux UART0 */
+ ldr r5,=0x1021a2
+ ldr r6,=0x40048080
+ str r5, [r6, #0x0]
+ ldr r5,=0x1021a1
+ ldr r6,=0x40048084
+ str r5, [r6, #0x0]
+
+ /* Set IOMUX for DDR pads */
+ ldr r11, [r0, #PM_INFO_VF610_IOMUXC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_IOMUXC_DDR_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_IOMUXC_DDR_IO_VAL_OFFSET
+ add r7, r7, r0
+
+loop_iomuxc_ddr_restore:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+ bne loop_iomuxc_ddr_restore
+
+
+ /* Enable slow oscilators */
+ ldr r11, [r0, #PM_INFO_VF610_SCSC_P_OFFSET]
+
+ ldr r5, [r11, #VF610_SCSC_SOSC]
+ orr r5, r5, #VF610_SCSC_SOSC_SOSC_EN
+ str r5, [r11, #VF610_SCSC_SOSC]
+
+ ldr r5, [r11, #VF610_SCSC_SIRC]
+ orr r5, r5, #VF610_SCSC_SIRC_SIRC_EN
+ str r5, [r11, #VF610_SCSC_SIRC]
+
+ /* Enable fast osciallator */
+ ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET]
+
+ ldr r5, [r11, #VF610_CCM_CLPCR]
+ bic r5, r5, #VF610_CCM_CLPCR_DIS_REF_OSC
+ bic r5, r5, #VF610_CCM_CLPCR_FXOSC_PWRDWN
+ str r5, [r11, #VF610_CCM_CLPCR]
+
+ ldr r5, [r11, #VF610_CCM_CCR]
+ orr r5, r5, #VF610_CCM_CCR_FXOSC_EN
+ str r5, [r11, #VF610_CCM_CCR]
+
+ ldr r5, [r11, #VF610_CCM_CCSR]
+ orr r5, r5, #VF610_CCM_CCSR_FAST_CLK_SEL
+ str r5, [r11, #VF610_CCM_CCSR]
+
+ ldr r11, [r0, #PM_INFO_VF610_ANATOP_P_OFFSET]
+
+ /* Select external FXOSC */
+ ldr r5, [r11, #VF610_ANADIG_MISC0]
+ bic r5, r5, #VF610_ANADIG_MISC0_CLK_24M_IRC_XTAL_SEL
+ str r5, [r11, #VF610_ANADIG_MISC0]
+
+ /* pll1 enable */
+ add r6, r11, #VF610_ANADIG_PLL1_CTRL
+ enable_syspll r6
+
+ /* enable pll2 only if required for DDR */
+ ldr r5, [r0, #PM_INFO_CCM_CCSR]
+ tst r5, #VF610_CCM_CCSR_DDRC_CLK_SEL
+ bne switch_sysclk
+
+ /* pll2 enable */
+ add r6, r11, #VF610_ANADIG_PLL2_CTRL
+ enable_syspll r6
+
+switch_sysclk:
+
+ /* Enable PFD and switch to fast clock */
+ ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET]
+
+ /* Get previous CCSR/CACRR settings */
+ ldr r5, [r0, #PM_INFO_CCM_CCSR]
+ str r5, [r11, #VF610_CCM_CCSR]
+
+ ldr r5, [r0, #PM_INFO_CCM_CACRR]
+ str r5, [r11, #VF610_CCM_CACRR]
+
+ /* Restore memory configuration */
+ ldr r11, [r0, #PM_INFO_VF610_DDRMC_P_OFFSET]
+
+ ldr r6, [r0, #PM_INFO_DDRMC_IO_NUM_OFFSET]
+ ldr r7, =PM_INFO_DDRMC_IO_VAL_OFFSET
+ add r7, r7, r0
+
+ /* Clear start bit of first memory register, do not start yet... */
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ bic r9, r9, #VF610_DDRMC_CR00_START
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+
+loop_ddrmc_restore:
+ ldr r8, [r7], #0x4
+ ldr r9, [r7], #0x4
+ str r9, [r11, r8]
+ subs r6, r6, #0x1
+ bne loop_ddrmc_restore
+
+ /* Set PWUP_SREF_EX to avoid a full memory initialization */
+ ldr r6, [r11, #VF610_DDRMC_CR33]
+ orr r6, r6, #VF610_DDRMC_CR33_PWUP_SREF_EX
+ str r6, [r11, #VF610_DDRMC_CR33]
+
+ /* Start initialization */
+ ldr r6, =VF610_DDRMC_CR80_INIT_COMPLETE
+ str r6, [r11, #VF610_DDRMC_CR81]
+
+ ldr r6, [r11, #VF610_DDRMC_CR00]
+ orr r6, r6, #VF610_DDRMC_CR00_START
+ str r6, [r11, #VF610_DDRMC_CR00]
+
+ddrmc_initializing:
+ ldr r5, [r11, #VF610_DDRMC_CR80]
+ ands r5, r5, #VF610_DDRMC_CR80_INIT_COMPLETE
+ beq ddrmc_initializing
+
+ resume_ddrmc r11
+
+ /* LP-Mode: RUN */
+ ldr r11, [r0, #PM_INFO_VF610_GPC_P_OFFSET]
+ ldr r5, =0x0
+ str r5, [r11, #VF610_GPC_LPMR]
+
+ /* Enable SNVS */
+ ldr r3, [r0, #PM_INFO_VF610_CCM_P_OFFSET]
+ ldr r4, [r3, #VF610_CCM_CCGR6]
+ orr r4, r4, #0x0000C000
+ str r4, [r3, #VF610_CCM_CCGR6]
+
+ /* Enable SNVS access (RTC) */
+ ldr r11, =0x400a7000
+ ldr r4, =0x80000100
+ str r4, [r11, #0x4]
+
+ /* get physical resume address from pm_info. */
+ ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+
+ ret lr
+ENDPROC(vf610_suspend)
+